VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 3561|回复: 3

[交流] boost正則之xpressive

[复制链接]
zuiwuchang 发表于 2016-7-12 12:48:32 | 显示全部楼层 |阅读模式
本帖最后由 zuiwuchang 于 2016-7-12 12:50 编辑

boost 提供了 兩個處理 正則表達式的庫 Regex Xpressive (孤亦是為了處理 正則表達式 才開始玩boost 之後便不能自已)
Regex 最初出現在 1.18.0        (亦成為c++11 新標準 可在c++11中 直接使用)
Xpressive 最初出現在 1.34.0

然在boost 中如果 要使用Regex 需要編譯 Xpressive則不需要

Xpressive 使用一般就兩步
1        使用正則語法 創建一個 匹配模式(Xpressive 使用 Perl語法 https://zh.wikipedia.org/wiki/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F
2        將匹配模式 和待處理字符串 傳入 相應函數 進行 匹配 替換 查詢 ...

  1. #include <boost/xpressive/xpressive.hpp>

  2. //只使用 靜態語法
  3. //#include <boost/xpressive/xpressive_static.hpp>
  4. //只使用 動態語法
  5. //#include <boost/xpressive/xpressive_dynamic.hpp>


  6. int _tmain(int argc, _TCHAR* argv[])
  7. {
  8.         //創建匹配模式 匹配gmail
  9.         //動態語法
  10.         boost::xpressive::cregex d_gmail = boost::xpressive::cregex::compile("[a-z0-9]+@gmail.com",boost::xpressive::icase);
  11.         //靜態語法
  12.         boost::xpressive::cregex s_gmail = +boost::xpressive::set[
  13.                 boost::xpressive::range('a','z') |
  14.                 boost::xpressive::range('A','Z') |
  15.                 boost::xpressive::range('0','9')
  16.         ]>>"@gmail.com";
  17.         

  18.         //匹配
  19.         std::cout<<boost::xpressive::regex_match("test0L@gmail.com",d_gmail)<<"\n";
  20.         std::cout<<boost::xpressive::regex_match("test0L@gmail.com",s_gmail)<<"\n";

  21.         return 0;
  22. }
复制代码


Xpressive為匹配模式 提供了4個類 cregex sregex wcregex wsregex它們是 basic_regex 分別 對 char* std::string wchar_t* std::wstring 的特化 用於處理相應 字符串

Xpressive 提供了如下 幾個方法 用於 將字符串 安模式 進行處理
                        bool regex_match(str,reg)                          返回字符串str是否 和模式reg匹配
                        bool regex_search(str,what,reg);                                查找第一個匹配的子串
                        str regex_replace(str,reg,ecma262)                將字符串str中 匹配reg的 部分使用 ecma262語法替換
                        xxx_iterator(begin,end,reg)                        返回所有匹配reg的子串
                        xxx_token_iterator(begin,end,reg)                使用reg進行分詞
注意除了regex_match使用 完全匹配外 其他幾個方法 都使用部分匹配

匹配
見上文例子

查找
  1. std::string str="this is a power-suip item this is a power-wuit item";
  2.         
  3.         boost::xpressive::sregex reg = boost::xpressive::sregex::compile("(power)-(.{4})");

  4.         //定義返回結果
  5.         boost::xpressive::smatch what;
  6.         //regex_search查找
  7.         if(regex_search(str,what,reg))
  8.         {
  9.                 //獲取匹配子串
  10.                 for(boost::xpressive::smatch::const_iterator iter=what.begin();iter!=what.end();++iter)
  11.                 {
  12.                         std::cout<<*iter<<std::endl;
  13.                 }
  14.                 /*for(int i=0;i<what.size();++i)
  15.                 {
  16.                         std::cout<<what[i]<<std::endl;
  17.                 }*/
  18.         }
  19.         
  20.         return 0;
复制代码
boost::xpressive::smatch 的第一個 元素是 匹配的 子串 其後元素 是模式中 每個匹配 (...) 中的 內容


替換

  1. std::string str="readme.txt readme.txt ";

  2.         boost::xpressive::sregex reg = boost::xpressive::sregex::compile("(.*)(me)");

  3.         std::cout<<regex_replace(str,reg,"c++")<<std::endl;

  4.         //ecma-262 語法 [        DISCUZ_CODE_145        ]amp;代表被匹配的原字符串 $n 代表正則表達式中第n個()內地字符串
  5.         std::cout<<regex_replace(str,reg,"$1abc")<<std::endl;
  6.         std::cout<<regex_replace(str,reg,"[        DISCUZ_CODE_145        ]amp;[        DISCUZ_CODE_145        ]amp;")<<std::endl;
  7.         std::cout<<regex_replace(str,reg,"$1abc$2")<<std::endl;
  8.         
  9.         return 0;
复制代码

返回子串
  1. std::string str;
  2.         for(int i=0;i<=20;++i)
  3.         {
  4.                 str += "begin";

  5.                 str += boost::lexical_cast<std::string>(i);
  6.                 str += "end";
  7.         }
  8.         boost::xpressive::sregex reg = boost::xpressive::sregex::compile("(begin)(.{0,2})(end)");

  9.         boost::xpressive::sregex_iterator iterator(str.begin(),str.end(),reg);
  10.         boost::xpressive::sregex_iterator end;
  11.         while(iterator!=end)
  12.         {
  13.                 std::cout<<(*iterator)[0]<<std::endl;
  14.                 ++iterator;
  15.         }

  16.         return 0;
复制代码

分詞

  1. std::string str;
  2.         for(int i=0;i<20;++i)
  3.         {
  4.                 str += boost::lexical_cast<std::string>(i);
  5.                 str += "||";
  6.         }
  7.         boost::xpressive::sregex reg1 = boost::xpressive::sregex::compile("\\|\\|");
  8.         boost::xpressive::sregex reg2 = boost::xpressive::sregex::compile("\\d+");

  9.         //最後一個參數傳入 -1 則將正則表達式 作為分隔符
  10.         boost::xpressive::sregex_token_iterator iterator1(str.begin(),str.end(),reg1,-1);
  11.         boost::xpressive::sregex_token_iterator end;
  12.         while(iterator1!=end)
  13.         {
  14.                 std::cout<<*iterator1<<std::endl;
  15.                 ++iterator1;
  16.         }

  17.         //將正則表達式作為 要查找的元素
  18.         boost::xpressive::sregex_token_iterator iterator2(str.begin(),str.end(),reg2);
  19.         while(iterator2!=end)
  20.         {
  21.                 std::cout<<*iterator2<<std::endl;
  22.                 ++iterator2;
  23.         }

  24.         return 0;
复制代码


评分

参与人数 1驿站币 +1 热心值 +1 收起 理由
二蛋 + 1 + 1 支持原创!

查看全部评分

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

kissy286 发表于 2016-7-12 15:37:31 | 显示全部楼层
非常的赞!!

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

zskk1 发表于 2016-7-13 22:37:24 来自手机 | 显示全部楼层
我就笑笑不说话1468449487.11

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

zskk1 发表于 2016-7-13 22:40:39 来自手机 | 显示全部楼层
我就笑笑不说话1468449487.11

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入驿站

本版积分规则

展开

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号 )

返回顶部
x

VC驿站微信公众号cctry2009

GMT+8, 2017-12-14 04:24

Powered by Discuz!

© 2009-2017 cctry.com

快速回复 返回顶部 返回列表