zoukankan      html  css  js  c++  java
  • c++ 正則表達式

    正則表達式是经常使用的一种方法。比較有名的类库是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[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"; //邮箱


  • 相关阅读:
    “三路九招”打赢电商低成本营销战
    我的文章分类
    ResourceBundle读取中文properties文件问题
    敏捷基础知识
    一个简单方法:构造xml的document,并将其转换为string
    在android源码环境下写上层应用的一个初步解决方法
    Linux 与 unix shell编程指南——学习笔记
    git 分支的基本操作
    使用repo的本地开发流程
    Linux常用命令收集
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4491961.html
Copyright © 2011-2022 走看看