资讯专栏INFORMATION COLUMN

[C/C++ C++11]正则表达式

Object / 1547人阅读

摘要:文档介绍楷体正则文法正则库表示有一个正则表达式类,比如全文匹配,要求整个字符串符合正则表达式的匹配规则。能和正则表达式相匹配就返回替换匹配,即可以将符合匹配规则的子字符串替换为其他字符串。

一、为什么要学正则表达式
若要判断一个输入的QQ号是否有效,如何判断?
判断步骤:

  1. 长度大于5,小于等于10;
  2. 首位不能为0;
  3. 是否为纯数字?

C++string处理:

#includeusing namespace std;int main(){    string qq = "7466a2063";    if (qq.length() >= 5 && qq.length() <= 11)    {        // 2. 判断是否非"0"开头        if (qq[0] != "0")        {            // 3. 判断是否为纯数字            for each (char var in qq)            {                cout << var;                if (var < "0" || var > "9")                {                    cout << "不存在" << endl;                    return 0;                }            }            cout << "存在" << endl;        }        else        {            cout << "不存在" << endl;        }    }    else    {        cout << "不存在" << endl;    }    return 0;}

虽然功能实现了但是非常麻烦

#include#includeusing namespace std;int main(){    regex qq_reg("[1-9]//d{4,11}");    string qq = "746632063";    smatch result;    bool ret = regex_match(qq, result, qq_reg);    cout << (ret ? "存在" : "不存在") << endl;    return 0;}

正则表达式只需几行代码就行了。

是不是很方便呢?那么接下来便来看看C++如何使用正则表达式

二、正则程序库(regex)
C++11 新增了正则表达式的标准库支持,本文简介 C++ 正则表达式的使用:
std::regex是C++用来表示正则表达式(regular expression)的库,它是class std::basic_regex<>针对char类型的一个特化,还有一个针对wchar_t类型的特化为std::wregex。
文档介绍

正则文法:

正则库:

regex
表示有一个正则表达式类,比如:regex pattern("(.{3})(.{2})_(/d{4})!")
regex_match
全文匹配,要求整个字符串符合正则表达式的匹配规则。用来判断一个字符串和一个正则表达式是否模式匹配,返回一个 bool 值,true 为匹配,false 为不匹配。匹配的含义是目标字符串必须完全和正则表达式相匹配,不能有多余的字符,如果需要部分匹配则应使用regex_search
regex_search 搜索匹配,根据正则表达式来搜索字符串中是否存在符合规则的子字符串。 能和正则表达式相匹配就返回true
regex_replace
替换匹配,即可以将符合匹配规则的子字符串替换为其他字符串。要求输入一个正则表达式,以及一个用于替换匹配子字符串的格式化字符串。这个格式化字符串可以通过转义序列引用匹配子字符串中的部分内容
sregex_iterator
迭代器适配器,调用regex_search来遍历一个string中所有匹配的子串
smatch/match_results
容器类,保存在string中搜索的结果。如果匹配成功,这些函数将成功匹配的相关信息保存在给定的smatch对象中。比如:smatch results;将匹配结果存放在results中,另一种存储方法声明:match_resultsstring::const_iterator result

匹配(Match)
字符串处理常用的一个操作是匹配,即字符串和规则恰好对应,而用于匹配的函数为std::regex_match(),它是个函数模板

bool regex_match(string s,regex pattern)
bool regex_match(string s,smatch result,regex pattern)
bool regex_match(s.cbegin()+i,s.cend(),smatch result,regex pattern)

参数s为要匹配的字符串,pattern为匹配规则,result保存结果s.cbegin()+i,s.cend()对应s的匹配s迭代器所取的范围。

更多的时候我们希望能够获得匹配结果(字符串),对结果进行操作。这时就需要对匹配结果进行存储,共有两种存储方式。

match_resultsstring::const_iterator result;
smatch result; //推荐

如果需要保存结果,可以用第二种函数,用smatch result保存结果。
通常result[0]保存整个匹配结果,result[i]保存第i个捕获组的匹配结果,即模式中第i个括号的匹配结果。如果没有这样的结果则为空。
可以用result.size()查看一共有多少个匹配结果。

#include#includeusing namespace std;int main(){	string str = "Hello_2021";	smatch result;	regex pattern("(.{5})_(//d{4})");	//匹配5个任意单字符 + 下划线 + 4个数字	if (regex_match(str, result, pattern))	{		cout << result[0] << endl;		//完整匹配结果,Hello_2018		cout << result[1] << endl;		//第一组匹配的数据,Hello		cout << result[2] << endl;		//第二组匹配的数据,2018		cout << "结果显示形式2" << endl;		cout << result.str() << endl;	//完整结果,Hello_2018		cout << result.str(1) << endl;	//第一组匹配的数据,Hello		cout << result.str(2) << endl;	//第二组匹配的数据,2018	}	//遍历结果	for (int i = 0; i < result.size(); ++i)	{		cout << result[i] << endl;	}}

result结构为如下图,result[0]为匹配的字符串,result[1]为Hello result[2]为2021

result[]与result.str()这两种方式能够获得相同的值,我更喜欢用数组形式的。
在匹配规则中,以括号()的方式来划分组别,实例中的规则共有两个括号,所以共有两组数据

搜索(Search)

搜索与匹配非常相像,其对应的函数为std::regex_search,也是个函数模板,用法和regex_match一样,不同之处在于搜索只要字符串中有目标出现就会返回,而非完全匹配。

bool regex_search(string s,regex pattern)
bool regex_search(string s,smatch result,regex pattern)
bool regex_search(s.cbegin()+i,s.cend(),smatch result,regex pattern) //从字符串的某个位置开始匹配?

string str = "Hello 2018, Bye 2017";smatch result;regex pattern("//d{4}");	//匹配四个数字//迭代器声明string::const_iterator iterStart = str.begin();string::const_iterator iterEnd = str.end();string temp;while (regex_search(iterStart, iterEnd, result, pattern)){	temp = result[0];	cout << temp << " ";	iterStart = result[0].second;	//更新搜索起始位置,搜索剩下的字符串}输出结果:2018 2017

搜索给定字符串中是否存在与模式匹配的子串,如果存在则返回true。

同样可以用smatch result记录结果,但不同的是result[0]记录的是整个字符串中从左往右第一个匹配模式的子串。

假如有多个子串符合模式,若想知道result[0]中存储的是第几个子串,可以用result.position()函数,返回数从0开始。

替换(Replace)
replace是替换匹配,即可以将符合匹配规则的子字符串替换为其他字符串。

string regex_replace(string s,regex p,string replace_str)

string str = "Hello_2021!";regex pattern("Hello");	cout << regex_replace(str, pattern, "") << endl;	cout << regex_replace(str, pattern, "Hi") << endl;	

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/125068.html

相关文章

  • 惊爆!一行正则达式引发的 CPU 惨案

    摘要:我将上面校验的正则表达式的第二部分后面加多了个号,即变成这样这里加了个号这样之后,运行原有的程序就没有问题了。 正则表达式是程序员经常使用的工具之一。本文作者通过一个正则表达式的陷阱,先深入剖析了出现问题的原因,后给出怎么处理这类问题的方法。最后还给出了一些检测常见正则表达式问题的工具,十分值得深入研究。前几天线上一个项目监控信息突然报告异常,上到机器上后查看相关资源的使用情况,发现 CPU...

    Faremax 评论0 收藏0
  • 【JS基础】正则达式入门

    摘要:对于含有量词正则表达式,量词是贪婪模式,会优先选择尽可能多的匹配修饰的字符,所以该表达式会优先选择匹配一个字符,当匹配不到时再选择不匹配字符。 正则表达式的语法 普通字符 字母、数字、汉字、下划线以及一些没有特殊定义的标点符号,都属于普通字符,正则表达式中的普通字符匹配字符本身,如: var str = abced console.log(str.match(/a/)) // [a,...

    Mr_houzi 评论0 收藏0
  • 爆肝1万字《c++入门综合》

    摘要:大家好,今天屁孩君给大家带来入门综合。年,标准委员会发布了语言的第一个国际标准,该标准即为大名鼎鼎的。年,标准委员会发布了一份技术报告,详细说明了计划引入的新特性。年月日,经过标准委员投票,标准获得一致通过。 ...

    _Dreams 评论0 收藏0
  • php性能怎么优化?php性能优化及安全策略

    摘要:性能问题一般不会超过占整个项目性能的,一般在。内置函数的性能优劣。几乎与在函数中调用局部变量的速度相当。递增一个全局变量要比递增一个局部变量慢倍。类似的方法调用所花费的时间接近于次的局部变量递增操作。 php性能怎么优化?性能是网站运行是否良好的关键因素, 网站的性能与效率影响着公司的运营成本及长远发展,编写出高质高效的代码是我们每个开发人员必备的素质,也是我们良好...

    番茄西红柿 评论0 收藏2637
  • 正则达式迷你书-笔记

    摘要:使用看完你就会正则表达式了四种操作验证切分提取替换第一章正则表达式字符匹配攻略正则表达式是匹配模式,要么匹配字符,要么匹配位置至少,至多匹配中的任一个字符范围表示法如果要匹配则要么要么要么通配符,表示几乎任意 API 使用 String#search String#split String#match String#replace RegExp#test Reg...

    IamDLY 评论0 收藏0

发表评论

0条评论

Object

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<