c++ 正則表達式

时间:2021-12-18 05:03:23

正則表達式是经常使用的一种方法。比較有名的类库是boost,可是这个类库在重了。全部就像找一些轻量级的类库。

后来发现准标准的库tr1已经非常方便了,微软vs2008 sp1 以上版本号都支持了。全部就直接用它非常方便了。

并且支持unicode编码,还是非常方便的。

样例:

#include <iostream>  

#include <string>  

#include <regex>  

  

int _tmain(int argc, _TCHAR* argv[])  

{  

    std::locale loc("");  

    std::wcout.imbue(loc);  

  

    std::wstring text(_T("我的IP地址是:109.168.0.1."));  

    std::wstring newIP(_T("127.0.0.1"));  

    std::wstring regString(_T("(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"));  

  

    // 表达式选项 - 忽略大写和小写  

    std::regex_constants::syntax_option_type fl = std::regex_constants::icase;  

      

    // 编译一个正則表達式语句  

    std::wregex regExpress(regString, fl);  

  

    // 保存查找的结果  

    std::wsmatch ms;  

  

    // 推断是否全行匹配  

    if(std::regex_match(text, ms, regExpress))  

    {  

        std::wcout<<_T("正則表達式:")<<regString<<_T("匹配:")<<text<<_T("成功.")<<std::endl;  

    }  

    else  

    {  

        std::wcout<<_T("正則表達式:")<<regString<<_T("匹配:")<<text<<_T("失败.")<<std::endl;  

    }  

  

    // 查找  

    if(std::regex_search(text, ms, regExpress))  

    {  

        std::wcout<<_T("正則表達式:")<<regString<<_T("查找:")<<text<<_T("成功.")<<std::endl;  

        for(size_t i= 0; i < ms.size(); ++i)  

        {  

            std::wcout<<_T("第")<<i<<_T("个结果:\"")<<ms.str(i)<<_T("\" - ");  

            std::wcout<<_T("起始位置:")<<ms.position(i)<<_T("长度")<<ms.length(i)<<std::endl;  

        }  

        std::wcout<<std::endl;  

  

        // 替换1  

        text = text.replace(ms[0].first, ms[0].second, newIP);  

        std::wcout<<_T("替换1后的文本:")<<text<<std::endl;  

    }  

    else  

    {  

        std::wcout<<_T("正則表達式:")<<regString<<_T("查找:")<<text<<_T("失败.")<<std::endl;  

    }  

  

    // 替换2  

    newIP = _T("255.255.0.0");  

    std::wstring newText = std::regex_replace( text, regExpress, newIP);  

    std::wcout<<_T("替换2后的文本:")<<newText<<std::endl;  

  

    // 结束  

    std::wcout<<_T("按回车键结束...");  

    std::wcin.get();  

    return 0;

}

循环取:

std::regex_constants::syntax_option_type fl = std::regex_constants::icase;      

const std::tr1::regex pattern("http://[^\\\"\\>\\<]+?\\.(png|jpg|bmp)",fl);       

std::tr1::smatch result;      

std::string::const_iterator itS = strHtml.begin();  

std::string::const_iterator itE = strHtml.end();      

while(regex_search(itS,itE, result, pattern))//假设匹配成功  

{          

    //m_clbRegex.AddString((CString)result[0].str().c_str());           

    m_clbRegex.AddString((CString)(string(result[0].first,result[0].second)).c_str());          

    itS=result[0].second;//新的位置開始匹配      

}

[代码说明]

1. 创建正則表達式对象,有3中方法:

(1) 使用构造函数

std::regex_constants::syntax_option_type fl = std::regex_constants::icase; // 语法选项,能够设置使用哪种风格的正則表達式语法等.

std::wregex regExpress(regString, fl);

(2) 使用赋值运算符,缺点是不能指定语法选项,并且也比較低效.

std::wregex regExpress;

regExpress = regString;

(3) 使用assign方法.

std::wregex regExpress;

regExpress.assign(regString, fl);

构造正则对象的过称就是所谓的"编译".



2. regex_match() 和 regex_search()

regex_match()仅仅有在整个字符串匹配正則表達式时才返回 true, 而 regex_search()在子串匹配就返回 true.



3. 匹配结果对象 std::wsmatch.

熟悉Perl正則表達式的人都知道,匹配成功后能够用 $1 $2 ... $N 来获得子串的指, tr1 regex库把匹配结果保存在一个 std::wsmatch(UNICODE) / std::smatch(ANSI) 对象中.

std::wsmatch 是一个由若干个 std::wssub_match 对象构成的数组. 而 std::wssub_match 派生自 pair.

由std::wssub_match::first保存子串的起始位置指针(事实上说是迭代器比較准确一点).

由std::wssub_match::second保存子串的结束位置 +1 的指针(STL的通用原则,半开区间).

所以 [std::wssub_match::first,std::wssub_match::second) 就是子串的所有内容.

当然, std::wsmatch (match_result模版的提前定义类) 提供了一些简便的方法用于訪问子串:

(1) str(idx) 方法返回相应的子串的 std::string / std::wstring 对象. 仅仅是最经常使用的.

(2) position(idx) 方法返回相应子串的起始偏移量.(不是指针,是相对于首字节地址或者begin()的偏移量).

(3) length(idx) 返回子串的长度.



4. 替换子串.

前面说到 std::wssub_match::first / second 保存了子串的起始/结束位置,那么我们当然能够用这个指针(迭代器)来替换文本(见代码中的 "替换1").

或者用 std::regex_replace() 也能够达到目的(见代码中的"替换2").

几个经常使用的表达式:

"\\b1[35][0-9]\\d{8}|147\\d{8}|1[8][01236789]\\d{8}\\b";//手机号

 "\\b0\\d{2,3}\\-?\\d{7,8}\b"; //座机

 "\\b[1-9]\\d{5}(?:19|20)\\d{2}(?:0[1-9]|[1][012])(?#月)(?:0[1-9]|[12][0-9]|[3][01])(?#日)\\d{3}[\d|X|x]\\b"; //18位身份证

 "\\b[1-9]\\d{7}(?:0[1-9]|[1][012])(?#月)(?:0[1-9]|[12][0-9]|[3][01])(?#日)\\d{3}\\b"; //15位身份证

"\\b(?:(?:2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(?:2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\b";  //ip4

"\\b(?:[a-zA-Z0-9_-])+@(?:[a-zA-Z0-9_-])+(?:\\.[a-zA-Z0-9_-]{2,3}){1,2}\\b"; //邮箱

c++ 正則表達式的更多相关文章

  1. js正則表達式语法

    1. 正則表達式规则 1.1 普通字符 字母.数字.汉字.下划线.以及后边章节中没有特殊定义的标点符号,都是"普通字符".表达式中的普通字符,在匹配一个字符串的时候,匹配与之同样的 ...

  2. Java正則表達式入门

     众所周知,在程序开发中,难免会遇到须要匹配.查找.替换.推断字符串的情况发生,而这些情况有时又比較复杂,假设用纯编码方式解决,往往会浪费程序猿的时间及精力.因此,学习及使用正則表達式,便成了解决这一 ...

  3. jquery&plus;正則表達式验证邮箱格式的样例

    js: $("#email").blur(function(){ //获取id相应的元素的值,去掉其左右的空格 var email = $.trim($('#email').val ...

  4. python使用正則表達式

    python中使用正則表達式 1. 匹配字符 正則表達式中的元字符有 .  ^  $ *   +  ?  { }  [ ]  \  | ( ) 匹配字符用的模式有 \d 匹配随意数字 \D 匹配随意非 ...

  5. Java正則表達式语法

    Java正則表達式语法 字符 说明 \ 将下一字符标记为特殊字符.文本.反向引用或八进制转义符.比如,"n"匹配字符"n"."\n"匹配换行 ...

  6. javascript正則表達式 &amp&semi;quot&semi;&bsol;b&amp&semi;quot&semi;问题

    preface 昨晚在看<javascript权威指南>后.看见作者自己封装一个兼容全部浏览器的山寨HTML5新API classLIst类.自己想了想认为自己也要去玩一下.可是能力还是有 ...

  7. C&plus;&plus;11中正則表達式測试

    VC++2010已经支持regex了, 能够用来编译下述代码. #include <string> #include <regex> #include <iostream ...

  8. 深入浅出理解iOS经常使用的正則表達式—基础篇&lbrack;Foundation&rsqb;

    參考资料:cocoachina的zys475481075的文章 几个单词 Regular ['regjʊlə]adj. 定期的:有规律的 Expression[ɪk'spreʃ(ə)n; ek-] n ...

  9. Linux正則表達式-反复出现的字符

    星号(*)元字符表示它前面的正則表達式能够出现零次或多次.也就是说,假设它改动了单个字符.那么该字符能够在那里也能够不在那里,而且假设它在那里,那可能会不止出现一个.能够使用星号元字符匹配出如今引號中 ...

  10. Java正則表達式

    近期工作中常常要用到正則表達式,不得不花点时间对其进行一定的学习.   JDK中提供了2个类来支持正則表達式,各自是java.util.regex.Pattern和java.util.regex.Ma ...

随机推荐

  1. 解决类似 Requires&colon; libstdc&plus;&plus;&period;so&period;6&lpar;GLIBCXX&lowbar;3&period;4&period;15&rpar;&lpar;64bit&rpar;的问题

    源码编译升级安装了gcc后,编译程序或运行其它程序时,有时会出现类似/usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found的问题.这 ...

  2. RancherOS Hyper-V 安装

    RancherOS Hyper-V 安装, Install to disk 打开 Hyper-V 管理界器, 新建虚拟机 输入名称和存储位置 选择一代 最低 1024M 配置网络 创建虚拟磁盘 设置启 ...

  3. 由浅到深讲解C&num;-LINQ

    在说LINQ之前必须先说说几个重要的C#语言特性 一:与LINQ有关的语言特性 1.隐式类型 (1)源起 在隐式类型出现之前, 我们在声明一个变量的时候, 总是要为一个变量指定他的类型 甚至在fore ...

  4. 206&period; Reverse Linked List

    反转链表 注意是借用  假的头节点,这样算法判断开始和结束,就好很多了. 借用头插法. []dummy/head [] [] [] [] head  curr ==== class Solution ...

  5. mac配置iterm2和ohmyzsh

    点击我直通 iTerm2下载 利用命令下载ohmyzsh curl -L http://install.ohmyz.sh | sh 安装好之后,运行 vi ~/.zshrc 可以查看到以下配置内容信息 ...

  6. HW1&period;7

    public class Solution { public static void main(String[] args) { System.out.println("π = " ...

  7. NS2仿真:使用NS仿真软件模拟简单网络模型

    NS2仿真实验报告1 实验名称:使用NS仿真软件模拟简单网络模型 实验日期:2015年3月2日~2015年3月7日 实验报告日期:2015年3月8日 一.实验环境(网络平台,操作系统,网络拓扑图) 运 ...

  8. debian 64位系统中添加对32位的支持

    dpkg --add-architecture i386 apt-get update apt-get install ia32-libs

  9. iOS回顾笔记(07) -- UITableView的使用和性能优化

    iOS回顾笔记(07) -- UITableView的使用和性能优化 如果问iOS中最重要的最常用的UI控件是什么,我觉得UITableView当之无愧!似乎所有常规APP都使用到了UITableVi ...

  10. CSS3弹性伸缩布局(中)——flexbox布局

    混合过渡版 上一篇我们主要讲了旧版box布局,今天这篇主要讲flexbox布局. 混合版本的Flexbox模型是2011年提出的工作草案,主要是针对IE10浏览器实现的伸缩布局效果,其功能和旧版本的功 ...