关于c++正则表达式的用法
本人最近在做一个项目,这个项目里面有一个功能是这样的,要求这个项目中提供搜索功能,简单的说,如果里面输入1-10 11,15,27,39这个字符串,那么你就要从中找到1,2,3,4,5,6,7,8,9,10和11,15,27,39等等这些数字。我考虑了很久,决定使用正则表达式来做,采用的原因有两点:其一,因为考虑到范围的问题(比如说位数不能超过三位)这样的话采用正则表达式比较好处理。其二,考虑到格式的问题,因为如果说写一个abc-def e,r,t,y,u这种类型的话,我在切割之后还需要进行判断,这样很不好处理,因此我考虑了很久,决定采用正则表达式来处理这件事情。
一、设计这部分的思路
二、c++正则表达式的基本用法
2.1 前言
2.2 正则的匹配条件
2.3 c++中正则表达式的三种用法
三、具体的实现步骤
四、总结
考虑到各种情况:
1、1-10 (截取出来的数字1,2,3,4,5,6,7,8,9,10)
2、23,45,57(截取出来的数字为23,45,57)
3、1-10 23,45,57(截取出来的数字1,2,3,4,5,6,7,8,9,10,23,45,57)
4、23,45,57 1-10(截取出来的数字1,2,3,4,5,6,7,8,9,10,23,45,57)
当然,这里要说明一下,目前这个算法有一个部分就是如果只输入单一数字23那么是没有办法处理的,这个需要在代码上补齐一下这种可能性。
ok,我们开始设计算法了,我的想法是这样的:因为这是两部分,所以首先将整个字符串拆分成两部分,在分别处理,各自解析出相关的数字之后,在将他们统一放到vector的数组中。所以,综上所述,整个算法可以分成三个部分来进行处理。
1、将字符串拆分成两部分(第一部分为1-10这部分,第二部分为后面的逗号部分)
2、第二部分解析相应的数字
3、将其存放到一个全局的vector中(之所以使用全局因为后期给其他回调线程用)
二、c++中正则表达式的用法
2.1 前言
首先说一下,本人以前学过正则了,用过shell中grep的正则表达式,c++中的正则表达式和shell中的还是有一定区别的。
不过在匹配条件上确实都差不多。
2.2 正则表达式的条件
正则表达式的条件有很多,如果一个一个记太麻烦了,所以我归类总结了一下,可以分成三类:
1、关于括号的用法:
():表示分组(这个过会说明怎么用)
{} : 表示匹配的次数(简单来说{3,5}表示匹配至少3次,至多5次,当然也可以拆开来用)
顺便说下,没有中括号
2、关于内容的匹配
首先我们想到内容匹配一共有三种,分别是数字,字母,空格,所以正则表达式为我们也提供了六种相应的
匹配内容的方法(因为有取反),分别是:
\d:数字
\D:不匹配数字
\w:匹配字母
\W:不匹配字母
\s:匹配空格
\S: 不匹配空格
3、占位符:
这里要说道四种占位符
.:匹配任意单个字符
?:匹配字符0次或者1次
*:匹配字符任意次
+:匹配字符1次到无数次
4、其他字符
^:表示开始匹配
$:表示终止匹配
|:多个条件匹配
2.3 关于c++正则匹配的三种模式
首先说一下,c++正则的用法全部都在regex库中(这里说一下,因为我用的是c++11的库,所以到底之前库能不能用我也不知道),而其中有三种匹配模式,分别为:
regex_match(string,std::regex):匹配全部字符的
regex_search(string,std::regex):匹配部分字符的
regex_replace(string,std::regex, string):用来替换相应字符的
当然这里说一下,无论式match也好,还是search也好,默认匹配第一个字符比如我的字符串是1994 1994 1994 1994,那么他默认只匹配输出第一个1994。
三、具体的实现步骤
好的,搞清楚了regex的基本用法,我们就可以开始使用他了。首先我们来实现第一步,拆分字符串。以1-10 11,15,27,39为例子,我们可以这样写:
匹配1-10的字符串可以这样写
bool seperateStr(string str)
{
std::regex pattern("(\\d+)-(\\d+)+"); //这里说明下,第一个和第二个加号表示前面和后面的两个数字可以无限位,第三个加号考虑到可能出现比如1-10 11-20这种情况,所以这样设计
smatch result; // 这个可以输出结果
string::const_iterator iter = str.begin;
string::const_iterator iterEnd = str.end;
string temp;
std::vector<string> vv1;
while(regex_search(iter, iterEnd, result, pattern)) {
temp = result[0];
vv1.push_back(temp);
iter = result[0].second; //这里要说一下,因为之前说了,它是默认匹配第一个的,所以说匹配成功后要把
初始指针向后移动
}
iter = str.begin;
std::vector<string> vv2;
std::regex pattern1 ("((\\d+),(\\d+)+)|(,(\\d+)+)|((\\s\\d+)+)|((\\d+\\\s))"); //针对各种情况设计的匹配条件,这里不做解释了
while(regex_search(iter, iterEnd,result, pattern1) {
temp = result[0];
vv2.push_back(temp);
iter = result[0].second;
}
}
通过这样,就可以把里面的内容分开了
OK,搞定了这个问题,我们实现第二部算法,这个式这样的
bool range(std::vector vv1)
{
// 这里的实现步骤与上面基本一致,只需要把匹配条件稍作修改
std::regex pattern("\\d+");
}
3、最后把解析出的数据放到全局变量vector中,整个部分就完成了。
四、总结
本文主要针对我做的一个小开发对正则表达式进行了理解和说明。
posted on 2020-09-13 18:30 碧海无波,细水长流 阅读(1562) 评论(0) 编辑 收藏 举报