关于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中,整个部分就完成了。

    四、总结

      本文主要针对我做的一个小开发对正则表达式进行了理解和说明。