歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

C++ Tr1中的正則表達式

要使用正則表達式,首先要有類庫支持,C++以前不像Java或者C#有完整的類庫使用,但是在Tr1中早已提供了正則庫,只是很少被人們注意罷了

TR1中包含了一個正則庫,來自Boost的 regex,已經納入了0x新標准,但是新標准遙遙無期。即便如此,現在很多編譯器也已經支持了,特別是微軟,步伐最快!

雖然現在新標准還未完全支持,但是早點了解一下也是好的:

#include <iostream>
#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;
}

[代碼說明]
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").

使用的VC2010,一般2008 sp1以上都支持正則表達式。

Copyright © Linux教程網 All Rights Reserved