正則表達(dá)式是常用的一種方法。比較有名的類庫(kù)是boost,但是這個(gè)類庫(kù)在重了。所有就像找一些輕量級(jí)的類庫(kù)。
后來(lái)發(fā)現(xiàn)準(zhǔn)標(biāo)準(zhǔn)的庫(kù)tr1已經(jīng)很方便了,微軟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+)")); // 表達(dá)式選項(xiàng) - 忽略大小寫 std::regex_constants::syntax_option_type fl = std::regex_constants::icase; // 編譯一個(gè)正則表達(dá)式語(yǔ)句 std::wregex regExpress(regString, fl); // 保存查找的結(jié)果 std::wsmatch ms; // 判斷是否全行匹配 if(std::regex_match(text, ms, regExpress)) { std::wcout<<_T("正則表達(dá)式:")<<regString<<_T("匹配:")<<text<<_T("成功.")<<std::endl; } else { std::wcout<<_T("正則表達(dá)式:")<<regString<<_T("匹配:")<<text<<_T("失敗.")<<std::endl; } // 查找 if(std::regex_search(text, ms, regExpress)) { std::wcout<<_T("正則表達(dá)式:")<<regString<<_T("查找:")<<text<<_T("成功.")<<std::endl; for(size_t i= 0; i < ms.size(); ++i) { std::wcout<<_T("第")<<i<<_T("個(gè)結(jié)果:\"")<<ms.str(i)<<_T("\" - "); std::wcout<<_T("起始位置:")<<ms.position(i)<<_T("長(zhǎng)度")<<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("正則表達(dá)式:")<<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; // 結(jié)束 std::wcout<<_T("按回車鍵結(jié)束..."); std::wcin.get(); return 0;
}
循環(huán)?。?/p>
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;//新的位置開(kāi)始匹配 }
[代碼說(shuō)明] 1. 創(chuàng)建正則表達(dá)式對(duì)象,有3中方法: (1) 使用構(gòu)造函數(shù) std::regex_constants::syntax_option_type fl = std::regex_constants::icase; // 語(yǔ)法選項(xiàng),可以設(shè)置使用哪種風(fēng)格的正則表達(dá)式語(yǔ)法等. std::wregex regExpress(regString, fl); (2) 使用賦值運(yùn)算符,缺點(diǎn)是不能指定語(yǔ)法選項(xiàng),而且也比較低效. std::wregex regExpress; regExpress = regString; (3) 使用assign方法. std::wregex regExpress; regExpress.assign(regString, fl); 構(gòu)造正則對(duì)象的過(guò)稱就是所謂的"編譯".
2. regex_match() 和 regex_search() regex_match()只有在整個(gè)字符串匹配正則表達(dá)式時(shí)才返回 true, 而 regex_search()在子串匹配就返回 true.
3. 匹配結(jié)果對(duì)象 std::wsmatch. 熟悉Perl正則表達(dá)式的人都知道,匹配成功后可以用 $1 $2 ... $N 來(lái)獲得子串的指, tr1 regex庫(kù)把匹配結(jié)果保存在一個(gè) std::wsmatch(UNICODE) / std::smatch(ANSI) 對(duì)象中. std::wsmatch 是一個(gè)由若干個(gè) std::wssub_match 對(duì)象構(gòu)成的數(shù)組. 而 std::wssub_match 派生自 pair. 由std::wssub_match::first保存子串的起始位置指針(其實(shí)說(shuō)是迭代器比較準(zhǔn)確一點(diǎn)). 由std::wssub_match::second保存子串的結(jié)束位置 +1 的指針(STL的通用原則,半開(kāi)區(qū)間). 所以 [std::wssub_match::first,std::wssub_match::second) 就是子串的全部?jī)?nèi)容. 當(dāng)然, std::wsmatch (match_result模版的預(yù)定義類) 提供了一些簡(jiǎn)便的方法用于訪問(wèn)子串: (1) str(idx) 方法返回對(duì)應(yīng)的子串的 std::string / std::wstring 對(duì)象. 只是最常用的. (2) position(idx) 方法返回對(duì)應(yīng)子串的起始偏移量.(不是指針,是相對(duì)于首字節(jié)地址或者begin()的偏移量). (3) length(idx) 返回子串的長(zhǎng)度.
4. 替換子串. 前面說(shuō)到 std::wssub_match::first / second 保存了子串的起始/結(jié)束位置,那么我們當(dāng)然可以用這個(gè)指針(迭代器)來(lái)替換文本(見(jiàn)代碼中的 "替換1"). 或者用 std::regex_replace() 也可以達(dá)到目的(見(jiàn)代碼中的"替換2").
幾個(gè)常用的表達(dá)式:
"\\b1[35][0-9]\\d{8}|147\\d{8}|1[8][01236789]\\d{8}\\b";//手機(jī)號(hào) "\\b0\\d{2,3}\\-?\\d{7,8}\b"; //座機(jī) "\\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"; //郵箱
|