正則表達式是经常使用的一种方法。比較有名的类库是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+正則表達式验证邮箱格式的样例

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

  4. python使用正則表達式

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

  5. Java正則表達式语法

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

  6. javascript正則表達式 &quot;\b&quot;问题

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

  7. C++11中正則表達式測试

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

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

    參考资料: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. uva 10817 - Headmaster's Headache ( 状态压缩dp)

    本文出自   http://blog.csdn.net/shuangde800 题目链接: 点击打开链接 题目大意 某校有n个教师和m个求职者,已知每人的工资和能教的课程集合,要求支付最少的工资使得每 ...

  2. Codeforces 480C Riding in a Lift dp

    主题链接:点击打开链接 意甲冠军: 特定 n a b k 构造一个长度k该序列. 使得序列中 对于随意两个相邻的数 | w[i-1] - w[i] | < | w[i] - b | 且第一个数 ...

  3. Android清除缓存功能来实现

    我们都知道在Android的设置->应用程序中能够查看应用程序的相关信息,当中有一个功能是清除缓存. 如图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZ ...

  4. js实现双击后网页自己主动跑-------Day55

    公司的界面设计环节总算是告一段落了,必需要承认的是,这段时间晚间的学习带给我非常多益处.在工作中偶尔的应用,效果出奇的好,收到领导和同事的一些小赞扬,表示非常欣慰,也长了点不少自信,尽管不理解,他们这 ...

  5. CMap与hash_map效率对照

    CMap与hash_map底层均採用hash stable实现,CMap是MFC提供的模板类.hash_map尽管眼下并未纳入C++标准模板类库,但差点儿每一个版本号的STL都提供了对应的实现.CMa ...

  6. JavaScript中的分号插入机制

    原文:JavaScript中的分号插入机制 仅在}之前.一个或多个换行之后和程序输入的结尾被插入 也就是说你只能在一行.一个代码块和一段程序结束的地方省略分号. 也就是说你可以写如下代码 functi ...

  7. AFNetWorking POST Multi-Part Request 上传图片

    这些天来,做图片上传的时候,我遇到一个问题.对我来说,这只是一个附加的图片将请求超时,这里是代码: AFHTTPRequestOperationManager *manager = [AFHTTPRe ...

  8. 阐述linux IPC(两):基于socket进程间通信(下一个)

    [版权声明:尊重原创.转载请保留源:blog.csdn.net/shallnet 要么 .../gentleliu,文章学习交流.请勿用于商业用途]     其中两个进程通信,有两个过程,以彼此的过程 ...

  9. 我学的是设计模式的视频教程——装饰图案,装饰图案VS代理模式

    课程视频 装饰模式 装饰模式VS代理模式1 装饰模式VS代理模式2 课程笔记 课程笔记 课程代码 课程代码 新课程火热报名中 课程介绍 版权声明:本文博主原创文章,博客,未经同意不得转载.

  10. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(6)- EF上下文实例管理

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(6)- EF上下文实例管理 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    ( ...