正則表達式是经常使用的一种方法。比較有名的类库是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. Struts2详细说明

    最近学习Struts2,阅读一些好的博客.收集有关. 原博文地址:http://blog.csdn.net/zz_mm/article/details/5460397 1.    深入Struts2的 ...

  2. github中origin和upstream的区别(转)

    Fork,本身并不是git工具中的一个命令,也不是对git的扩展,它是在GitHub上的概念,是另一种clone方式——在服务器端的clone.而我们通常意义上的clone,是将远程repo 复制一份 ...

  3. Web在线视频方案浅谈

    写在前面 最近因为项目预研,花时间和精力了解并总结了现如今web在线视频的一些解决方案,由于资历薄浅,措辞或是表述难免出现遗漏,还望各位海涵,有好的建议或方案还望赐教,定细心学习品位. 如今的web技 ...

  4. remine chart2安装

    http://blog.csdn.net/kufeiyun/article/details/9213911

  5. The Swift Programming Language中国完整版

    近来的ios的swift语言似乎火了.我没有objectc基金会,但在此之前有c随着java在...的基础上.从几天开始学习ios的swift语言,晚发表在博客形式.下面是英文版本翻译swif图书.还 ...

  6. git 配置多个SSH-Key(转)

    摘要 我们在日常工作中会遇到公司有个gitlab,还有些自己的一些项目放在github上.这样就导致我们要配置不同的ssh-key对应不同的环境. 目录[-] 1,生成一个公司用的SSH-Key 2, ...

  7. Linux学习笔记——举例说,makefile 添加宏定义

    0.前言     从学习C语言開始就慢慢開始接触makefile,查阅了非常多的makefile的资料但总感觉没有真正掌握makefile.假设自己动手写一个makefile总认为非常吃力. 所以特意 ...

  8. MySQL定义和变量赋值

    变量可以在子程序(性能.存储过程.匿名块)声明和使用.这些变量的范围是在BEGIN...END规划. 变量的定义 语法格式: DECLARE var_name [, var_name]... data ...

  9. HDU - 5008 Boring String Problem (后缀数组+二分法+RMQ)

    Problem Description In this problem, you are given a string s and q queries. For each query, you sho ...

  10. UVA 10870 - Recurrences(矩阵高速功率)

    UVA 10870 - Recurrences 题目链接 题意:f(n) = a1 f(n - 1) + a2 f(n - 2) + a3 f(n - 3) + ... + ad f(n - d), ...