当前位置: 首页 > news >正文

C++-字符串处理函数-查找-截取-分割-替换-删除-格式化-与数值互转-拼接-正则表达式-常用功能

文章目录

    • 1.字符串查找
      • 1.1.find-正向查找
      • 1.2.rfind-逆向查找
    • 2.字符串子字符串截取
    • 3.字符串分割
    • 4.字符串替换-删除
    • 5.字符串裁剪-裁剪空字符串
    • 6.字符串格式化
    • 7.类型转换-数字转字符串-std::to_string()
    • 8.类型转换-字符串转数字
      • 8.1.字符串转双精度-std::stod
      • 8.2.字符串转单精度-std::stof
      • 8.3.字符串转整数-std::stoi
      • 8.4.字符串转长整数-std::stol
      • 8.5.字符串转长双精度-std::stold
      • 8.6.字符串转长长整型-std::stoll
      • 8.7.字符串转无符号长整型-std::stoul
      • 8.8.字符串转无符号长长整型-std::stoull
    • 9.字符串类型判断-是否是数值
    • 10.字符串拼接+append
    • 11.字符串数组拼接成字符串-Join
    • 12.正则表达式
      • 12.1.std::regex_match--是否匹配
      • 12.2.std::match_results-匹配结果
      • 12.3.std::regex_search-搜索匹配
      • 12.4.std::regex_search-替换匹配
      • 12.5.常用的正则表达式字符串

1.字符串查找

1.1.find-正向查找

第一个参数为待查找的子字符串。第二个参数为开始查找的位置(下标);如果不指明,则从第0个字符开始查找。如果未查找到,该返回值是一个很大的数据。用std::string::npos表示。

#include <iostream>
#include <string>
using namespace std;
int main()
{
	std::string str("defgabc");
	std::string::size_type pos = str.find("abc");
	if (pos == std::string::npos)//未找到
	{
		cout << "Not find" << endl;
	}
	return 0;
}

1.2.rfind-逆向查找

用法与find相同。

2.字符串子字符串截取

substr()是C++字符串函数,主要功能是复制子字符串,要求从指定位置开始,并具有指定的长度。如果没有指定长度_Count或_Count+_Off超出了源字符串的长度,则子字符串将延续到源字符串的结尾。

std::string x = s.substr();       //默认时的长度为从开始位置到尾
std::string y = s.substr(5);      //获得字符串s中 从第5位开始到尾的字符串
std::string z = s.substr(5, 3);   //获得字符串s中 从第5位开始的长度为3的字符串

3.字符串分割

标准C++里面没有带字符串分割函数,但是这个函数非常常用,作者实现并测试这个功能如下:

#include <string>
#include <vector>

std::vector<std::string> SplitWithStl(const std::string str, const std::string pattern)
{
	//如果为空则返回
	std::vector<std::string> strItems;
	if ("" == str)
	{
		return strItems;
	}

	//方便截取最后一段数据
	std::string strs = str + pattern;
	size_t pos = strs.find(pattern);
	size_t patternSize = pattern.length();
	//循环截取直到最后
	while (pos != std::string::npos)
	{
		//从开始位置到分隔符位置
		std::string x = strs.substr(0, pos);
		strItems.push_back(x);
		//截取剩下的字符串
		strs = strs.substr(pos + patternSize);
		pos = strs.find(pattern);
	}
	return strItems;
}

int main()
{
	std::string str1 = "45;;okfd;;kujh";
	std::string pat = ";;";

	std::vector<std::string> strItems = SplitWithStl(str1, pat);
	return 0;
}

4.字符串替换-删除

标准C++里面没有带字符串替换函数,但是这个函数非常常用,作者实现并测试这个功能如下:

#include <iostream>
#include <string>
#include <vector>
//字符串替换
std::string ReplaceStr(std::string str, const std::string oldStr, const std::string newStr)
{
	size_t newStrLen = newStr.length();
	size_t oldStrLen = oldStr.length();
	for (std::string::size_type pos(0); pos != std::string::npos; pos += newStrLen)
	{
		pos = str.find(oldStr, pos);
		if (pos != std::string::npos)
			str.replace(pos, oldStrLen, newStr);
		else
			break;
	}
	return str;
}
int main()
{
	std::string str1 = "45;;okfd;;kujh";
	std::string pat = ";;";

	std::string rlt=ReplaceStr(str1, pat, "+---++");
	return 0;
}

注意:如果新字符为空,等同于删除旧的子字符串。

5.字符串裁剪-裁剪空字符串

裁切首尾的空字符,对于一些信息处理系统比较常用,作者实现并测试这个功能如下:

#include <string>
std::string StringTrim(std::string str)
{
	if (str.empty()) {
		return str;
	}
	str.erase(0, str.find_first_not_of(" "));
	str.erase(str.find_last_not_of(" ") + 1);
	return str;
}
int main()
{
	std::string str1 = "  45;;okfd;;kujh  ";
	std::string pat = ";;";

	std::string rlt = StringTrim(str1);
	return 0;
}

6.字符串格式化

按照Format组合字符串,对于一些信息处理系统比较常用,作者实现并测试这个功能如下:

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <stdarg.h>
//字符串格式化
std::string StringFormat(const char *pszFmt, ...)
{
	std::string str;
	va_list args;
	va_start(args, pszFmt);
	{
		int nLength = _vscprintf(pszFmt, args);
		nLength += 1;  //上面返回的长度是包含\0,这里加上
		std::vector<char> vectorChars(nLength);
		_vsnprintf_s(vectorChars.data(), nLength, nLength, pszFmt, args);
		str.assign(vectorChars.data());
	}
	va_end(args);
	return str;
}
int main()
{
	std::string str1 = "45;;okfd;;kujh";
	std::string pat = ";;";

	std::string rlt = StringFormat("str=%s",str1.c_str());//原理还是对C的封装,不支持C++字符串类型。
	return 0;
}

7.类型转换-数字转字符串-std::to_string()

将数值转换为字符串。

std::string to_string( int value );  //与 std::sprintf(buf, "%d", value)
std::string to_string( long value ); //与 std::sprintf(buf, "%ld", value)
std::string to_string( long long value ); //与 std::sprintf(buf, "%lld", value)
std::string to_string( unsigned value ); //与 std::sprintf(buf, "%u", value)
std::string to_string( unsigned long value ); //与 std::sprintf(buf, "%lu", value)
std::string to_string( unsigned long long value );  //与 std::sprintf(buf, "%llu", value)
std::string to_string( float value ); //std::sprintf(buf, "%f", value) 
std::string to_string( double value ); //std::sprintf(buf, "%Lf", value) 
std::string to_string( long double value ); 

8.类型转换-字符串转数字

在C++11发布之前我们只能使用C语言的atoi等函数完成字符串到int/float/double等类型的转换,而在C++11中在std::string中自带了stoi/stod等工具函数进行转换。

8.1.字符串转双精度-std::stod

函数原型

double stod (const string&  str, size_t* idx = 0);
double stod (const wstring& str, size_t* idx = 0);

代码范例

std::string numStr = "5646545.32";
double number1 = std::stod(numStr);

注意:如果成功则返回转换的double型数值,如果转换失败,则会抛出invalid_argument异常,如果待转换的字符所代表的数值超出数值类型范围的两倍,则会抛出out_of_range异常。

8.2.字符串转单精度-std::stof

函数原型

float stof (const string&  str, size_t* idx = 0);
float stof (const wstring& str, size_t* idx = 0);

代码范例

std::string numStr = "5646545.32";
double number1 = std::stof(numStr);

注意:如果成功则返回转换的double型数值,如果转换失败,则会抛出invalid_argument异常,如果待转换的字符所代表的数值超出数值类型范围的两倍,则会抛出out_of_range异常。

8.3.字符串转整数-std::stoi

函数原型

//base : 转换字符所使用的进制数,如果为0,则使用的进制数由字符串的格式决定,默认值为10而不是0
int stoi (const string&  str, size_t* idx = 0, int base = 10);
int stoi (const wstring& str, size_t* idx = 0, int base = 10);

代码范例

std::string numStr = "5646545";
int number1 = std::stoi(numStr);

注意:如果成功则返回转换的double型数值,如果转换失败,则会抛出invalid_argument异常,如果待转换的字符所代表的数值超出数值类型范围的两倍,则会抛出out_of_range异常。

8.4.字符串转长整数-std::stol

函数原型

//base : 转换字符所使用的进制数,如果为0,则使用的进制数由字符串的格式决定,默认值为10而不是0
long stol (const string&  str, size_t* idx = 0, int base = 10);
long stol (const wstring& str, size_t* idx = 0, int base = 10);

代码范例

std::string numStr = "5646545";
int number1 = std::stol(numStr);

注意:如果成功则返回转换的double型数值,如果转换失败,则会抛出invalid_argument异常,如果待转换的字符所代表的数值超出数值类型范围的两倍,则会抛出out_of_range异常。

8.5.字符串转长双精度-std::stold

long double stold (const string&  str, size_t* idx = 0);
long double stold (const wstring& str, size_t* idx = 0);

8.6.字符串转长长整型-std::stoll

long long stoll (const string&  str, size_t* idx = 0, int base = 10);
long long stoll (const wstring& str, size_t* idx = 0, int base = 10);

8.7.字符串转无符号长整型-std::stoul

unsigned long stoul (const string&  str, size_t* idx = 0, int base = 10);
unsigned long stoul (const wstring& str, size_t* idx = 0, int base = 10);

8.8.字符串转无符号长长整型-std::stoull

unsigned long long stoull (const string&  str, size_t* idx = 0, int base = 10);
unsigned long long stoull (const wstring& str, size_t* idx = 0, int base = 10);

9.字符串类型判断-是否是数值

利用C++的输入特性来判断。

#include <sstream>
//是否为数字
static bool IsNum(std::string str)
{
	std::stringstream ss(str);
	double d;
	char c;
	if (!(ss >> d))
		return false;
	if (ss >> c)
		return false;
	return true;
}

10.字符串拼接+append

直接用+号,或者用string的append函数将字符串附加到末尾。

#include <string>
int main()
{
	std::string str1;
	str1 = "把握好眼前,";
	str1.append("努力");//直接附加到现有字符串末尾。
	//把握好眼前,努力
	return 0;
}

11.字符串数组拼接成字符串-Join

#include <vector>
#include <string>

//链接字符串
std::string StringJoin(std::vector<std::string>& strs,const std::string pattern)
{
	int size = strs.size();
	std::string rlt;
	for (int i = 0; i < size; i++)
	{
		if (i == 0)
		{
			rlt = strs[i] + pattern;
		}
		else if (i == size - 1)
		{
			rlt = rlt + strs[i];
		}
		else
		{
			rlt = rlt + strs[i] + pattern;
		}
	}
	return rlt;
}

int main()
{
	std::vector<std::string> strs = { "54","656" };
	std::string rlt=StringJoin(strs,"");
	return 0;
}

12.正则表达式

C++11 提供的正则表达式库操作 std::string 对象,模式 std::regex (本质是 std::basic_regex) 进行初始化,通过 std::regex_match 进行匹配,从而产生 std::smatch(本质是 std::match_results 对象)。

12.1.std::regex_match–是否匹配

#include <vector>
#include <iostream>
#include <string>
#include <regex>
int main() {
	std::string fnames[] = { "foo.txt", "bar.txt", "test", "a0.txt", "AAA.txt" };
	// 在 C++ 中 \ 会被作为字符串内的转义符,为使 \. 作为正则表达式传递进去生效,需要对 \ 进行二次转义,从而有 \\.
	std::regex txt_regex("[a-z]+\\.txt"); //表达式
	for (const auto &fname : fnames)
		std::cout << fname << ": " << std::regex_match(fname, txt_regex) << std::endl;

	return 0;
}

12.2.std::match_results-匹配结果

#include<iostream>
#include<string>
#include<regex>

int main()
{
	std::string fnames[] = { "foo.txt", "bar.txt", "test", "a0.txt", "AAA.txt" };
	// 在 C++ 中 \ 会被作为字符串内的转义符,为使 \. 作为正则表达式传递进去生效,需要
	std::regex base_regex("([a-z]+)\\.txt");
	std::match_results<std::string::const_iterator> base_match;
	for (const auto& fname : fnames)
	{
		if (std::regex_match(fname, base_match, base_regex))
		{
			// std::smatch 的第一个元素匹配整个字符串
			// std::smatch 的第二个元素匹配了第一个括号表达
			if (base_match.size() == 2) {
				std::string base = base_match[1].str();
				std::cout << "sub-match[0]: " << base_match[0].str() << std::endl;
				std::cout << fname << " sub-match[1]: " << base << std::endl;
			}
		}
	}

	return 1;
}

12.3.std::regex_search-搜索匹配

#include<regex>
#include<string>
#include<iostream>
int main()
{
	std::string str = "hello2012-12-12world!!!!!";
	std::match_results<std::string::const_iterator> match;
	std::regex pattern("(\\d{4})-(\\d{1,2})-(\\d{1,2})");

	if (std::regex_search(str, match, pattern))
	{
		for (size_t i = 1; i < match.size(); ++i)
		{
			std::cout << match[i] << std::endl;
		}
	}
	return 0;
}

12.4.std::regex_search-替换匹配

#include<regex>
#include<string>
#include<iostream>

int main()
{
	std::string str = "2019-08-07";
	std::cout << std::regex_replace(str, std::regex("-"), "/") << std::endl;//2019/08/07
	std::cout << str << std::endl;
	return 0;
}

12.5.常用的正则表达式字符串

检验数字表达式

数字:^[0-9]*$
n位的数字:^\d{n}$
至少n位的数字:^\d{n,}$
m-n位的数字:^\d{m,n}$
零和非零开头的数字:^(0|[1-9][0-9]*)$
非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
带1~2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})?$
正数,负数,和小数:^(\-|\+)?\d+(\.\d+)?$
有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
非零的正整数:^[1-9]\d*$或^([1-9][0-9]*){1,3}$或^\+?[1-9][0-9]*$
非零的负整数:^\-[1-9][]0-9″*$或^-[1-9]\d*$
非负整数:^\d+$或^[1-9]\d*|0$
非正整数:^-[1-9]\d*|0$或^((-\d+)|(0+))$
非负浮点数:^\d+(\.\d+)?$或^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$或^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
正浮点数:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$或^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$或^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
浮点数:^(-?\d+)(\.\d+)?$或^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$

检验字符串表达式

汉字:^[\u4e00-\u9fa5]{0,}$
英文和数字:^[A-Za-z0-9]+$或^[A-Za-z0-9]{4,40}$
长度为3~20的所有字符:^.{3,20}$
由26个英文字母组成的字符串:^[A-Za-z]+$
由26个大写英文字母组成的字符串:^[A-Z]+$
由26个小写英文字母组成的字符串:^[a-z]+$
由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
由数字,26个英文字母或者下划线组成的字符串:^\w+$或^\w{3,20}$
中文,英文,数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
中文,英文,数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$或^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
可以输入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+
禁止输入含有~的字符:[^~\x22]+

检验特殊表达式

Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
InternetURL:[a-zA-z]+://[^\s]*或^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
手机号码:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$
电话号码("XXX-XXXXXXX","XXXX-XXXXXXXX","XXX-XXXXXXX","XXX-XXXXXXXX","XXXXXXX"和"XXXXXXXX):^($$\d{3,4}-)|\d{3.4}-)?\d{7,8}$
国内电话号码(0511-4405222,021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
身份证号(15位,18位数字):^\d{15}|\d{18}$
短身份证号码(数字,字母x结尾):^([0-9]){7,18}(x|X)?$或^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$
帐号是否合法(字母开头,允许5~16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
密码(以字母开头,长度在6~18之间,只能包含字母,数字和下划线):^[a-zA-Z]\w{5,17}$
强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8~10之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
日期格式:^\d{4}-\d{1,2}-\d{1,2}
一年的12个月(01~09和1~12):^(0?[1-9]|1[0-2])$
一个月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$

相关文章:

  • LeetCode 790. 多米诺和托米诺平铺
  • Qt基础之四:Qt信号与槽机制原理及优缺点
  • 机器学习笔记 十七:基于Gini Importance、Permutation Importance、Boruta的随机森林模型重要性评估的比较
  • 大数据ClickHouse进阶(二十七):ClickHouse服务监控
  • 02 【nodejs开发环境安装】
  • 【Designing ML Systems】第 2 章 :机器学习系统设计简介
  • C++与C语言中的字符串
  • 8. 无线体内纳米网:基于蓝牙LE接口的数字ID系统
  • 极智AI | 昇腾 CANN ATC 模型转换
  • 富文本编辑器(添加列表)
  • 格理论与密码学-2-2-公钥密码体制和哈希函数
  • Vue框架的学习(Vue操作指令学习三 V-bind )第三课
  • C语言之指针(中)
  • neo4j-jdbc-driver这个坑货
  • 云存储系统架构及优势
  • Oracle SQL执行计划操作(1)——表相关操作
  • C语言实现三子棋小游戏(源码+教程)
  • 解读数据可用性赛道:如何讲好模块化区块链的叙事?
  • 如何进入 mysql?
  • java计算机毕业设计VUE商场库存管理系统MyBatis+系统+LW文档+源码+调试部署