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

        四、总结

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

  • 相关阅读:
    非专业码农 JAVA学习笔记 3 抽象、封装和类(1)
    非计算机专业的码农C#学习笔记 三、变量 表达式 字符串
    非专业码农 JAVA学习笔记 2 java语言基础
    非计算机专业的码农C#学习笔记 五、数组和集合
    PSP个人软件开发工具
    端口映射
    $.proxy()
    input type=button设置高度不管用
    移动端日期控件
    mac终端下svn常用命令
  • 原文地址:https://www.cnblogs.com/songyuchen/p/13661883.html
Copyright © 2020-2023  润新知