Boost学习之正则表达式--regex
來源:http://blog.chinaunix.net/uid-21222282-id-1829265.html
來源:http://www.cnblogs.com/undermoon/archive/2009/11/30/1613508.html
來源:http://blog.csdn.net/guyulongcs/article/details/7838753
來源:http://blog.csdn.net/leonardwang/article/details/6035171
boost::regex類為C++提供了完整的正則表達式支持,并且已被接收為C++0x標準庫。它同時也在Boost庫中扮演著極重要的角色,不少Boost子庫都需要它的支持,有不少人甚至就是為了它才下載使用Boost的。
boost::regex的默認正則表達式語法是perl語法
??????? boost::regex支持perl regular表達式、POSIX-Extended regular表達式和POSIX-Basic Regular表達式,但默認的表達式語法是perl語法,如果要使用其余兩種語法需要在構造表達式的時候明確指定。
??????? boost::regex使用ICU來實現對unicode及unicode變種的支持,這需要在編譯boost的時候指出是否使用ICU以及ICU所在 的目錄。否則編譯出來的boost::regex不支持unicode編碼。其中boost::wregex支持unicode編碼的搜索,如果要搜索 UTF-8、UTF-16、UFT-32編碼的字符串,則要用boost::u32regex。注意boost::wregex只能支持unicode編 碼,不能支持uft編碼。
搜索時如何忽略大小寫
??????? 如果要在搜索時忽略大小寫(即大小寫不敏感),則要用到表達式選項boost::regex::icase,例如: boost::regex e2(my_expression, boost::regex::perl|boost::regex::icase);
Boost Regex Libray類和接口介紹
(1)basic_regex
basic_regex是一個模板類,它封裝了正則表達式的解析和編譯,它是Boost.Regex中用來表示正則表達式的對象類型。Boost.Regex定義了兩種標準類型,一種是基于單字節字符的regex,另一種是基于寬字符的wregex
關于basic_regex提供的接口,和STL中basic_string所提供的十分類似,具體可以參考:
http://www.boost.org/doc/libs/1_37_0/libs/regex/doc/html/boost_regex/ref/basic_regex.html
(2)match_results
match_results是用來表示所有匹配指定正則表達式的字符串的集合的對象類型。Boost.Regex提供了四種標準類型的定義:C單字節字符類型的cmatch, C寬字符類型的wcmatch, C++單字節字符類型smatch, C++寬字符類型wsmatch。match_results所提供的接口參見:
http://www.boost.org/doc/libs/1_37_0/libs/regex/doc/html/boost_regex/ref/match_results.html
(3)sub_match
sub_match是用來表示匹配指定正則表達式的字符串的對象類型。match_results就是由sub_match組成的集合類型。
關于sub_match類型,有下面三點需要注意的:
a. sub_match類型的對象只能通過對match_results類型的對象取下標獲取
b. sub_match類型的對象可以和std:basic_string或const char*的字符串進行比較
c. sub_match類型的對象可以和std::basic_string或const char*的字符串相加,生成新的std::basic_string類型的字符串
sub_match所提供的接口請參考:
http://www.boost.org/doc/libs/1_37_0/libs/regex/doc/html/boost_regex/ref/sub_match.html
(4)reg_match, reg_search和reg_replace
reg_match, reg_search和reg_replace都是Boost.Regex所提供的具體進行正則匹配的算法接口。
reg_match用來判定整個字符串是否匹配指定的的正則表達式, 具體定義參見:
http://www.boost.org/doc/libs/1_37_0/libs/regex/doc/html/boost_regex/ref/regex_match.html
reg_search用來判定字符串的某一部分是否匹配指定的正則表達式, 具體定義參見:
http://www.boost.org/doc/libs/1_37_0/libs/regex/doc/html/boost_regex/ref/regex_search.html
reg_replace用來把字符串中匹配指定正則表達式的部分替換為指定內容輸出,對于不匹配的部分原樣輸出, 具體定義參見:
http://www.boost.org/doc/libs/1_37_0/libs/regex/doc/html/boost_regex/ref/regex_replace.html
#include <string> #include <iostream> #include "boost/regex.hpp" int main(int argc, char ** argv) { if (argc != 4) { std::cerr<<"Usage: " << argv[0] <<" option regex text\n" <<" option: 0 --whole match\n" <<" 1 --sub match\n" <<" 2 --replace match\n"; return 1; } boost::regex oRegex(argv[2]); boost::smatch oResults; std::string strStr(argv[3]); std::string strRes; switch (atoi(argv[1])) { case 0: if(boost::regex_match(strStr, oResults, oRegex)) { std::cout << strStr << " matches " << oRegex << "\n"; } else { std::cout << strStr << " doesn't match " << oRegex << "\n"; } break; case 1: if(boost::regex_search(strStr, oResults, oRegex)) { std::cout << strStr << " matches " << oRegex << "\n"; } else { std::cout << strStr << " doesn't match " << oRegex << "\n"; } break; case 2: strRes = boost::regex_replace(strStr, oRegex, ""); std::cout << "strRes=" << strRes << "\n"; break; default: std::cerr << "Invalid option: " << argv[1] << "\n"; break; } }
用法
要使用Boost.Regex, 你需要包含頭文件"boost/regex.hpp". Regex是本書中兩個需要獨立編譯的庫之一(另一個是Boost.Signals)。你會很高興獲知如果你已經構建了Boost— —那只需在命令提示符下打一行命令——就可以自動鏈接了(對于Windows下的編譯器),所以你不需要為指出那些庫文件要用而費心。
你要做的第一件事就是聲明一個類型 basic_regex 的變量。這是該庫的核心類之一,也是存放正則表達式的地方。創建這樣一個變量很簡單;只要將一個含有你要用的正則表達式的字符串傳遞給構造函數就行了。
boost::regex reg("(A.*)");注意使用Boost.Regex需要預先編譯
完整編譯請參考本站 編譯Boost的文章如果只要編譯Regex庫,有兩種方法(參考鏈接):
使用
模板類:
l???????? basic_regex????????? 用來保存一個“正則表達式”的類。
l???????? sub_match??????????? 繼承于pair<Iterator,Iterator>迭代器組,用來表示匹配的一個結果。
l???????? match_results???????????? sub_match的容器,用來表示一次搜索或匹配算法的所有結果,類似于vector<sub_match>。
算法:
l???????? regex_math?? 匹配算法,測試一個字符串是否和一個正則式匹配,并通過match_results返回結果。
l???????? regex_find???? 查找算法,查找字符串的一個和正則式匹配的字串,并通過match_results返回結果。
l???????? regex_format?????? 替換算法,查找字符串中的所有匹配正則式的字串,并使用“格式化字符”串替換。
迭代器:
l???????? regex_iterator????? 枚舉一個字符串中所有匹配的字串,regex_iterator的結果相當于match_results。
l???????? regex_token_iterator 枚舉一個字符串中所有匹配的字串,regex_iterator的結果相當于sub_match。
Boost.Regex手里有七種武器和兩****寶
其中的七種武器是:regex_match 函數 regex_search 函數 regex_replace 函數 regex_format 函數 regex_grep 函數 regex_split 函數 RegEx 類 每種武器都又有諸多變化( 每個函數都分別以C字符串類型、std::string類型、迭代器類型作為參數重載),不過后面四種武器因年久失修已不建議使用.
兩****寶是:
regex_iterator 迭代器 regex_token_iterator 迭代器 這兩****寶是整個Boost.Regex的靈魂,用熟它們以后那是“摘花飛葉即可傷人”啊~~
回到正題,下面邊寫邊學。
所需頭文件 #include <boost/regex.hpp>
示例代碼 :先準備一個測試用的數據備用,如果各位有雅興可以參考本站的另一篇文章《Google Testing》使用Google Testing框架來做這個實驗,花一樣時間學兩樣啊~~
1.字符串匹配
要確定一行字符串是否與指定的正則表達式匹配,使用regex_match。下面這個代碼可以驗證szStr字串(定義在上面)是否與szReg匹配。
{ //字符串匹配boost::regex reg( szReg );bool r=boost::regex_match( szStr , reg);assert(r); //是否匹配} boost::regex的構造函數中還可以加入標記參數用于指定它的行為,如:
//指定使用perl語法(默認),忽略大小寫。boost::regex reg1( szReg, boost::regex::perl|boost::regex::icase );//指定使用POSIX擴展語法(其實也差不多)boost::regex reg2( szReg, boost::regex::extended ); 下面這個代碼不僅驗證是否匹配,而且可以從中提取出正則表達式括號對應的子串。
{ //提取子串boost::cmatch mat;boost::regex reg( szStr );bool r=boost::regex_match( szStr, mat, reg);if(r) //如果匹配成功{//顯示所有子串for(boost::cmatch::iterator itr=mat.begin(); itr!=mat.end(); ++itr){// 指向子串對應首位置 指向子串對應尾位置 子串內容cout << itr->first-szStr << ' ' << itr->second-szStr << ' ' << *itr << endl;}}//也可直接取指定位置信息if(mat[4].matched) cout << "Path is" << mat[4] << endl;} 其中,boost::cmatch是一個針對C字符串的特化版本,它還有另三位兄弟,如下:
typedef match_results cmatch; typedef match_results smatch; typedef match_results wcmatch; typedef match_results wsmatch; 可以把match_results看成是一個sub_match的容器,同時它還提供了format方法來代替regex_format函數。
一個sub_match就是一個子串,它從std::pair繼承而來,這個迭代器pair里的first和second分別指向了這個子串開始和結尾所在位置。同時,sub_match又提供了str(),length()方法來返回整個子串。
2.查找字符串
regex_match只驗證是否完全匹配,如果想從一大串字符串里找出匹配的一小段字符串(比如從網頁文件里找超鏈接),這時就要使用regex_search了。下面這段代碼從szStr中找數字
{ //查找boost::cmatch mat;boost::regex reg( "\\d+" ); //查找字符串里的數字if(boost::regex_search(szStr, mat, reg)){cout << "searched:" << mat[0] << endl;}}
3.替換
regex_replace提供了簡便的方法來部分替換源字符串正則表達式中,使用$1~$9(或\1~\9)表示第幾個子串,$&表示整個串,$`表示第一個串,$'表示最后未處理的串。
{ //替換1,把上面的HTTP的URL轉成FTP的boost::regex reg( szReg );string s = boost::regex_replace( string(szStr), reg, "ftp://$2$5");cout << "ftp site:"<< s << endl;} 正則表達式中,使用(?1~?9新字串)表示把第幾個子串替換成新字串
{ //替換2,使用format_all參數把<>&全部轉換成網頁字符string s1 = "(<)|(>)|(&)";string s2 = "(?1<)(?2>)(?3&)";boost::regex reg( s1 );string s = boost::regex_replace( string("cout << a&b << endl;"), reg, s2, boost::match_default | boost::format_all);cout << "HTML:"<< s << endl;}
4.使用regex_iterator查找
對應于C字符串和C++字符串以及寬字符,regex_iterator同樣也有四個特化:typedef regex_iterator cregex_iterator; typedef regex_iterator sregex_iterator; typedef regex_iterator wcregex_iterator; typedef regex_iterator wsregex_iterator; 這個迭代器的value_type定義是一個match_results。
{ //使用迭代器找出所有數字boost::regex reg( "\\d+" ); //查找字符串里的數字boost::cregex_iterator itrBegin(szStr, szStr+strlen(szStr), reg);boost::cregex_iterator itrEnd;for(boost::cregex_iterator itr=itrBegin; itr!=itrEnd; ++itr){// 指向子串對應首位置 指向子串對應尾位置 子串內容cout << (*itr)[0].first-szStr << ' ' << (*itr)[0].second-szStr << ' ' << *itr << endl;}} Boost.Regex也提供了make_regex_iterator函數簡化regex_iterator的構造,如上面的itrBegin可以寫成:
itrBegin = make_regex_iterator(szStr,reg);
5.使用regex_token_iterator拆分字符串
它同樣也有四個特化,形式和上面類似,就不再寫一遍騙篇幅了。??? 這個迭代器的value_type定義是一個sub_match。
{ //使用迭代器拆分字符串boost::regex reg("/"); //按/符拆分字符串boost::cregex_token_iterator itrBegin(szStr, szStr+strlen(szStr), reg,-1);boost::cregex_token_iterator itrEnd;for(boost::cregex_token_iterator itr=itrBegin; itr!=itrEnd; ++itr){cout << *itr << endl;}} Boost.Regex也提供了make_regex_token_iterator函數簡化regex_token_iterator的構造,最后的那個參數-1表示以reg為分隔標志拆分字符串,如果不是-1則表示取第幾個子串,并且可以使用數組來表示同時要取幾個子串,例如:
{ //使用迭代器拆分字符串2boost::regex reg("(.)/(.)"); //取/的前一字符和后一字符(這個字符串形象貌似有點邪惡-_-)int subs[] = {1,2}; // 第一子串和第二子串boost::cregex_token_iterator itrBegin = make_regex_token_iterator(szStr,reg,subs); //使用-1參數時拆分,使用其它數字時表示取第幾個子串,可使用數組取多個串boost::cregex_token_iterator itrEnd;for(boost::cregex_token_iterator itr=itrBegin; itr!=itrEnd; ++itr){cout << *itr << endl;}}
參考
正則表達式教程聯機文檔
聯機文檔里幾個不錯的例子:
regex_search示例,演示找出C++代碼中所有的類定義regex_replace示例,演示以C/C++代碼作為輸入,輸出代碼高亮的HTML代碼
regex_iterator示例,regex_search示例的regex_iterator實現
regex_token_iterator示例,第二個例子演示了從一個HTML文件里提取出所的有鏈接地址
完整測試代碼:
#include <iostream> #include <boost/regex.hpp>using namespace std; int main(int argc, char* argv[]) { //( 1 ) (( 3 ) 2 )(( 5 )4)( 6 ) //(\w+)://((\w+\.)*\w+)((/\w*)*)(/\w+\.\w+)?//^協議://網址(x.x...x)/路徑(n個\字串)/網頁文件(xxx.xxx)const char *szReg = "(\\w+)://((\\w+\\.)*\\w+)((/\\w*)*)(/\\w+\\.\\w+)?";const char *szStr = "http://www.cppprog.com/2009/0112/48.html";{ //字符串匹配boost::regex reg( szReg );bool r=boost::regex_match( szStr , reg);assert(r);}{ //提取子串boost::cmatch mat;boost::regex reg( szReg );bool r=boost::regex_match( szStr, mat, reg);if(r) //如果匹配成功{//顯示所有子串for(boost::cmatch::iterator itr=mat.begin(); itr!=mat.end(); ++itr){// 指向子串對應首位置 指向子串對應尾位置 子串內容cout << itr->first-szStr << ' ' << itr->second-szStr << ' ' << *itr << endl;}}//也可直接取指定位置信息if(mat[4].matched) cout << "Path is" << mat[4] << endl;}{ //查找boost::cmatch mat;boost::regex reg( "\\d+" ); //查找字符串里的數字if(boost::regex_search(szStr, mat, reg)){cout << "searched:" << mat[0] << endl;}}{ //替換boost::regex reg( szReg );string s = boost::regex_replace( string(szStr), reg, "ftp://$2$5");cout << "ftp site:"<< s << endl;}{ //替換2,把<>&轉換成網頁字符string s1 = "(<)|(>)|(&)";string s2 = "(?1<)(?2>)(?3&)";boost::regex reg( s1 );string s = boost::regex_replace( string("cout << a&b << endl;"), reg, s2, boost::match_default | boost::format_all);cout << "HTML:"<< s << endl;}{ //使用迭代器找出所有數字boost::regex reg( "\\d+" ); //查找字符串里的數字boost::cregex_iterator itrBegin = make_regex_iterator(szStr,reg); //(szStr, szStr+strlen(szStr), reg);boost::cregex_iterator itrEnd;for(boost::cregex_iterator itr=itrBegin; itr!=itrEnd; ++itr){// 指向子串對應首位置 指向子串對應尾位置 子串內容cout << (*itr)[0].first-szStr << ' ' << (*itr)[0].second-szStr << ' ' << *itr << endl;}}{ //使用迭代器拆分字符串boost::regex reg("/"); //按/符拆分字符串boost::cregex_token_iterator itrBegin = make_regex_token_iterator(szStr,reg,-1); //使用-1參數時拆分,使用其它數字時表示取第幾個子串,可使用數組取多個串boost::cregex_token_iterator itrEnd;for(boost::cregex_token_iterator itr=itrBegin; itr!=itrEnd; ++itr){cout << *itr << endl;}}{ //使用迭代器拆分字符串2boost::regex reg("(.)/(.)"); //取/的前一字符和后一字符(這個字符串形象貌似有點邪惡-_-)int subs[] = {1,2}; // 第一子串和第二子串boost::cregex_token_iterator itrBegin = make_regex_token_iterator(szStr,reg,subs); //使用-1參數時拆分,使用其它數字時表示取第幾個子串,可使用數組取多個串boost::cregex_token_iterator itrEnd;for(boost::cregex_token_iterator itr=itrBegin; itr!=itrEnd; ++itr){cout << *itr << endl;}}cin.get();return 0; }1、完全匹配
std::string str("abcd");boost::regex reg( "a\\w*d" );if (regex_match(str, reg)){std::cout << str << " is match" << std::endl;}else{std::cout << str << " is not match" << std::endl;}2、完全匹配并獲取子串
const char* mail = "tengxun@qq.com";boost::cmatch res;//建立3個子表達式boost::regex reg("(\\w+)@(\\w+).(\\w+)");if (boost::regex_match(mail,res, reg)){//既可以通過迭代器獲取數據, 也可以通過數組方式獲取數據for (boost::cmatch::iterator pos = res.begin(); pos != res.end(); ++pos){std::cout << *pos << std::endl;}//res[0]存放匹配到的完整字符串std::cout << "name:" << res[1] << std::endl;}??? 3、查找, 當你不需要匹配整個字符串的時候,可以選擇查找
const char* mail = "tengxun@qq.com.cn";boost::cmatch res;//建立3個子表達式boost::regex reg("(\\w+)@(\\w+).(\\w+)");if (boost::regex_search(mail,res, reg)){std::cout <<"**************************************" << std::endl;//既可以通過迭代器獲取數據, 也可以通過數組方式獲取數據for (boost::cmatch::iterator pos = res.begin(); pos != res.end(); ++pos){std::cout << *pos << std::endl;}//res[0]存放匹配到的完整字符串std::cout << "match :" << res[0] << std::endl << "name:" << res[1] << std::endl;}??? 4、替換。 替換匹配到的子字符串, 可以通過$N 引用第N個匹配到的值、$&? 引用全匹配
#include <boost/algorithm/string.hpp> void TestReplace() {//將tengxun@qq.com.cn 替換成tengxun@139.com.cnstd::string mail("tengxun@qq.com.cn");//建立3個子表達式boost::regex reg("(\\w+)@(\\w+).(\\w+)");std::cout << boost::regex_replace(mail, reg, "$1@139.$3") << std::endl;std::cout << boost::regex_replace(mail, reg, "my$1@$2.$3") << std::endl;//自定義替換函數,regex_replace將匹配到的字符串數組傳遞給回調函數,由回調函數返回新的字符串std::cout << boost::regex_replace(mail, reg, [](const boost::smatch &m){return boost::to_upper_copy(m[0].str());}); }5、迭代。 當需要從字符串中提取多個表達式時,可以采用迭代進行提取
std::string str("tengxun@qq.com, aa@tt.com, bb@qq.com");boost::regex reg("(\\w+)@(\\w+).(\\w+)");boost::sregex_iterator pos(str.begin(), str.end(), reg);boost::sregex_iterator end;while(pos != end){std::cout << "[" << (*pos)[0] << "]";++pos;}??? 6、分詞
#include <iostream> #include <boost/regex.hpp> void TestToken() {using namespace std;using namespace boost;string str("tengxun@qq.com, aa@tt.com, bb@qq.com");regex reg("\\w+");sregex_token_iterator pos(str.begin(), str.end(), reg);while(pos != sregex_token_iterator()){cout << "[" << *pos << "]" ;++pos;}cout << endl;//如果最后一個參數args為-1,則把匹配到的字符串視為分隔符regex split_reg(",");pos = sregex_token_iterator(str.begin(), str.end(), split_reg, -1);while(pos != sregex_token_iterator()){cout << "[" << *pos << "]" ;++pos;}cout << endl;//如果最后一個參數args為正數,則返回匹配結果的第args個子串regex split_sub_reg("(\\w*)@(\\w*).(\\w*)");pos = sregex_token_iterator(str.begin(), str.end(), split_sub_reg, 1);while(pos != sregex_token_iterator()){cout << "[" << *pos << "]" ;++pos;}cout << endl;//匹配并指定輸出順序//從下面字符串中提取日期,并轉換成 年月日 的順序輸出std::string input("01/02/2003 blahblah 04/23/1999 blahblah 11/13/1981");regex re("(\\d{2})/(\\d{2})/(\\d{4})"); // find a dateint const sub_matches[] = { 3, 1, 2 }; // year,month, daysregex_token_iterator begin( input.begin(), input.end(), re, sub_matches ), end;// write all the words to std::coutstd::ostream_iterator< std::string > out_iter( std::cout, "\n" );std::copy( begin, end, out_iter ); } #include <iostream> #include <boost/regex.hpp> #include <string> using namespace std; using namespace boost; /*搜索字符串中是否含有子字符串 int main( int argc, char* argv[] ) {char *buf = "This is boost::regex example boost::regex";boost::regex exampleregex( "boost::regex" );boost::cmatch result;if( boost::regex_search( buf, result, exampleregex ) ){std::cout << result.str() << std::endl;}//boost::regex_replace(buf,)return 0; }*///寫了個去除左側無效字符(空格,回車,TAB)的正則表達式。 /*void main() {std::string testString = " /r/n Hello World ! GoodBye World/r/n";std::string TrimLeft = "([//s//r//n//t]*)(//w*.*)";boost::regex expression(TrimLeft);testString = boost::regex_replace( testString, expression, "$2" );std::cout<< "TrimLeft:" << testString <<std::endl; }*/ //關于重復的貪婪 /*void main() {std::string regstr = "(.*?)(age)(.*?)(//d{2})";boost::regex expression(regstr);std::string testString = "My age is 28 His age is 27";boost::smatch what;std::string::const_iterator start = testString.begin();std::string::const_iterator end = testString.end();while( boost::regex_search(start, end, what, expression) ){std::string name(what[1].first, what[1].second);std::string age(what[4].first, what[4].second);std::cout<< "Name:" << name.c_str() << std::endl;std::cout<< "Age:" <<age.c_str() << std::endl;start = what[0].second;}}*///regex_search學習 //regex_search與regex_match基本相同,只不過regex_search不要求全部匹配,即部份匹配(查找)即可。 //檢測字符串里是否含有數字 //簡單例子: /*void main() {std::string regstr = "(//d+)";boost::regex expression(regstr);std::string testString = "192.168.4.1";boost::smatch what;if( boost::regex_search(testString, expression) ){std::cout<< "Have digit" << std::endl;} } //用于打印出所有的數字 void main() {std::string regstr = "(//d+)";regstr = "(?<=(<a href="/" mce_href="/"")(.+?)(/">)(.+?)(?=</a>))";//regstr = "((?=<a href="/" mce_href="/"").+(?=/">.+</a>))";boost::regex expression(regstr);std::string testString = "sd<a href="/" mce_href="/""http:/www.baidu.com//" target='_blank'>aacc</a>fs<a href="/" mce_href="/""http:/www.baidu.com//">aacc</a>df192dfsd<a href="/" mce_href="/""http:/www.gjw123.com//">bbdd</a>.168sdfs.sdfs4dsf.sfdsd1asfscvasdf";boost::smatch what;std::string::const_iterator start = testString.begin();std::string::const_iterator end = testString.end();while( boost::regex_search(start, end, what, expression) ){std::cout<< "Have digit:" ;std::string msg(what[0].first, what[0].second);std::cout<< msg.c_str() << std::endl;start = what[0].second;}} */ //#include "stdafx.h" #include <cstdlib> #include <stdlib.h> #include <boost/regex.hpp> #include <string> #include <iostream> using namespace std; //using namespace boost; boost::wregex expression(L"^//s*我+//s*[想|愛|恨|扁]+//s*你"); int main(int argc, char* argv[]) {locale loc( "Chinese-simplified" );wcout.imbue(loc);std::wstring in = L"我我我我 愛愛愛愛愛 你";static boost::wsmatch what;cout << "enter test string" << endl;//getline(cin,in);if(boost::regex_match(in.c_str(), what, expression)){for(int i=0;i<what.size();i++)wcout<<L"str :"<<what[i].str()<<endl;}else{wcout<<L"Error Input"<<endl;}return 0; }/* #include <iostream> #include <string> #include <boost/regex.hpp> int main() {std::string str = "I'm singing while you're dancing.";std::string pattern = "(//b//w+(?=ing//b))";boost::regex ee_all(pattern);boost::smatch result;std::string::const_iterator it = str.begin();std::string::const_iterator end = str.end();while(boost::regex_search(it, end, result, ee_all)) {std::cout << result[0] << '/n';it = result[0].second;} } *//*void main() {std::string testString = "sdfs<a href="/" mce_href="/""http:/www.baidu.com//">aacc</a>df192dfsd<a href="/" mce_href="/""http:/www.gjw123.com//">bbdd</a>.168sdfs.sdfs4dsf.sfdsd1asfscvasdf";cmatch what;regex expression( "(?=<a//s+href=/"(.+?)/">(.+?)</a>)");if(regex_match(testString,what,expression)){int sun = what.size();cout<<sun<<endl;for(int i=0;i <what.size();i++);cout << "str: " <<what.str() <<endl;}else{cout << "Error "<<endl;}}*/ /* 四:regex_match例子代碼學習 1 我們經常會看一個字符串是不是合法的IP地址,合法的IP地址需要符合以下這個特征:xxx.xxx.xxx.xxx 其中xxx是不超過255的整數 正則表達式找到上面的這種形式的字符串相當容易,只是判斷xxx是否超過255就比較困難了(因為正則表達式是處理的文本,而非數字) OK,我們先來處理一個數字,即:xxx。找到一種表達式來處理這個數字,并且保證這個數字不會超過255 第一種情況:x,即只有一個數字,它可以是0~9 ,用/d 表示 第二種情況:xx,即有兩個數字,它可以是00~99,用/d/d 表示 第三種情況:xxx,這種情況分為兩種,一種是 1xx,可以用 1/d/d 表示另外一種是 2xx,這又分為兩種 2[1234]/d和 25[12345] 好了組合起來 1?/d{1,2}|2[1234]/d|25[12345] 既可以標識一個不大于255的數字字符串 嗯,我們現在需要重復這種情況既可: (1?/d{1,2}|2[1234]/d|25[12345])/.(1?/d{1,2}|2[1234]/d|25[12345])/.(1?/d{1,2}|2[1234]/d|25[12345])/.(1?/d{1,2}|2[1234]/d|25[12345]) 呵呵,長是長了點,我試圖用boost支持的子表達式縮短,但是沒有達到效果,請各位了解boost的正則表達式的達人指點: (1?/d{1,2}|2[1234]/d|25[12345])/./1$/./1$/./1$ (參看反向索引:http://www.boost.org/libs/regex/doc/syntax_perl.html 似乎反向只能匹配與第一個字符完全一樣的字符串,與我們的需求不同) Example:void main() {std::string regstr = "(1?//d{1,2}|2[1234]//d|25[12345])//.(1?//d{1,2}|2[1234]//d|25[12345])//.(1?//d{1,2}|2[1234]//d|25[12345])//.(1?//d{1,2}|2[1234]//d|25[12345])";boost::regex expression(regstr);std::string testString = "192.168.4.1";std::cout << "enter test string" << std::endl;std::getline(std::cin,testString);if( boost::regex_match(testString, expression) ){std::cout<< "This is ip address" << std::endl;}else{std::cout<< "This is not ip address" << std::endl;}std::getline(std::cin,testString); } */ //這個例子會把所有的IP的單個數字答應出來 // /*void main() {std::string regstr = "(1?//d{1,2}|2[1234]//d|25[12345])//.(1?//d{1,2}|2[1234]//d|25[12345])//.(1?//d{1,2}|2[1234]//d|25[12345])//.(1?//d{1,2}|2[1234]//d|25[12345])";boost::regex expression(regstr);std::string testString = "192.168.4.1";boost::smatch what;if( boost::regex_match(testString, what, expression) ){std::cout<< "This is ip address" << std::endl;for(int i = 1;i <= 4;i++){std::string msg(what[i].first, what[i].second);std::cout<< i << ":" << msg.c_str() << std::endl;}}else{std::cout<< "This is not ip address" << std::endl;}}*/ /* void main() {std::string regstr = "a+";boost::regex expression(regstr);std::string testString = "aaa";// 匹配至少一個aif( boost::regex_match(testString, expression) ){std::cout<< "Match" << std::endl;}else{std::cout<< "Not Match" << std::endl;} }*//* 找出非奇數字符 元字符用來表示取反。regex reg("[^13579]");它表示一個取反的字符類,可以匹配任意非奇數的字符。 void main() {regex reg("[^13579]");string s="012abcd3456789";sregex_iterator it(s.begin(),s.end(),reg);sregex_iterator end;while (it!=end)cout<<*it++; } *///當需要反復調用regex_search時,考慮使用這兩個iterator,比較方便。 /*int main() {regex reg(" ");char* s="123 456 789 12345";// cregex_token_iterator it; //This is correct, too.regex_token_iterator<char*> it(s,s+std::strlen(s),reg,-1);regex_token_iterator<char*> end;while (it!=end){cout<<*it++<<endl;}return 0; } */
總結
以上是生活随笔為你收集整理的Boost学习之正则表达式--regex的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CompletableFuture详解~
- 下一篇: b站 实时弹幕和历史弹幕 Protobu