簡(jiǎn)介1 正
則表達(dá)式(Regular
expression)是一種在文本處理中經(jīng)常用到的模式匹配的形式,可能許多用戶熟悉Unix下的grep,sed,awk等工具或者perl語(yǔ)言,它
們都廣泛地用到了正則表達(dá)式。傳統(tǒng)的C++用戶還受限于用POSIX C API's(Portable operateing system
interface standard)來(lái)操作正則表達(dá)式,而regex++已經(jīng)提供了這些API's,雖然它不一定是使用POSIX C
正則表達(dá)式庫(kù)的最好方法。比如regex++能處理寬字符字符串(wide character
strings),或者搜索、替換操作(在某種意義上類似于sed或perl),這些在傳統(tǒng)的C 庫(kù)中是不能實(shí)現(xiàn)的。 類boost::reg_expression是regex++庫(kù)中的關(guān)鍵類,它表示“機(jī)器可讀”的正則表達(dá)式,reg_expression 是在string的基礎(chǔ)之上構(gòu)建的,可以認(rèn)為它是一個(gè)具有string的功能,外加這個(gè)正則表達(dá)式算法所需要的狀態(tài)機(jī)。 像std::basic_string一樣,它提供了兩個(gè)針對(duì)char和wchar_t的特化版本:
namespace boost{ template <class charT, class traits = regex_traits<charT>, class Allocator = std::allocator<charT> > class basic_regex; typedef basic_regex<char> regex; typedef basic_regex<wchar_t> wregex; }
要知道regex++庫(kù)到底有什么用?可以試想我們要寫(xiě)一個(gè)信用卡處理程序。信用卡通常有16位數(shù)字組成的
號(hào)碼,其中每四位一組,用空格或連字號(hào)隔開(kāi)。在將這些信用卡號(hào)碼存入數(shù)據(jù)庫(kù)之前,我們難道不要檢驗(yàn)這些數(shù)字是否符合正確格式么?為了匹配任何一個(gè)數(shù)字我們
可以用正則表達(dá)式[0-9],數(shù)字串的寬度可以用[[:digit:]],當(dāng)然這些是POSIX標(biāo)準(zhǔn)。在regex++和perl中可簡(jiǎn)化為\d(注意許
多老的庫(kù)傾向于硬編碼到C-locale,因此這不是什么問(wèn)題)。下面的正則表達(dá)式可以檢驗(yàn)信用卡號(hào)碼的格式。 (\d{4}[- ]){3}\d{4} ()標(biāo)記子表達(dá)式,{4}表示重復(fù)4次。這僅是一個(gè)perl,awk,egrep的正則表達(dá)式的例子。regex++也支持那些sed,grep用到的比較老的“基本”語(yǔ)法,雖然它們很少用到,除非你需要重用一些已有的基本正則表達(dá)式。
現(xiàn)在讓我們把這個(gè)表達(dá)式置于C++代碼中來(lái)檢驗(yàn)信用卡號(hào)碼的格式:
bool validate_card_format(const std::string s) { static const boost::regex e("(\\d{4}[- ]){3}\\d{4}"); return regex_match(s, e); }
注意我們以前是如何將某些額外的轉(zhuǎn)義序列(或者翻譯成:轉(zhuǎn)義字符)添加到表達(dá)式的:要知道,正則表達(dá)式引擎處理轉(zhuǎn)義字符前,該轉(zhuǎn)義字符只能被 C++編譯器識(shí)別一次,因此,在C++代碼中嵌入正則表達(dá)式的轉(zhuǎn)義字符必須雙寫(xiě)(寫(xiě)兩次)。 還要注意到你的編譯器必須支持Koening lookup 2(比如VC6就不支持),否則你需要附加一些boost::prefixes到某些函數(shù)引用中。 那
些熟悉信用卡操作的人,可能還會(huì)想到上面的那種格式適合于人的閱讀,并不表示網(wǎng)上信用卡系統(tǒng)要求的格式(可能是16或15個(gè)沒(méi)有間隔符的數(shù)字串)。我們需
要一種簡(jiǎn)單的轉(zhuǎn)換方法,我們需要2個(gè)字符串,1個(gè)是正則表達(dá)式,一個(gè)是格式字符串(提供一種被匹配的內(nèi)容的描述)。在regex++中,search和
replace都能完成regex_merge算法,對(duì)于信用卡的例子我們給出了下面2個(gè)算法用于格式轉(zhuǎn)換:
// match any format with the regular expression: const boost::regex e("\\A(\\d{3,4})[- ]?(\\d{4})[- ]?(\\d{4})[- ]?(\\d{4})\\z"); const std::string machine_format("\\1\\2\\3\\4"); const std::string human_format("\\1-\\2-\\3-\\4");
std::string machine_readable_card_number(const std::string s) { return regex_merge(s, e, machine_format, boost::match_default | boost::format_sed); }
std::string human_readable_card_number(const std::string s) { return regex_merge(s, e, human_format, boost::match_default | boost::format_sed); }
這兒,我們用正則表達(dá)式中的子式把號(hào)碼分為4塊,format string 用類似sed的語(yǔ)法把被匹配的內(nèi)容替換為規(guī)定格式。 上面的例子中,我們還沒(méi)有直接操作匹配結(jié)果,匹配結(jié)果包括全體匹配和一些子式的匹配。當(dāng)需要正則表達(dá)式的匹配結(jié)果時(shí),就需要用到class match_results的實(shí)例,下面是常用類型的特化版本:
namespace boost{ typedef match_results<const char*> cmatch; typedef match_results<const wchar_t*> wcmatch; typedef match_results<std::string::const_iterator> smatch; typedef match_results<std::wstring::const_iterator> wsmatch; }
regex_search和regex_grep算法都使用到match_result。 注意這些算法并不局限于一般的C-strings,任何雙向迭代器(bidirectional iterator)類型都能被搜索,這為無(wú)縫搜索任何類型數(shù)據(jù)提供了可能性。
對(duì)于那些不喜歡模板(templates)的人還可以使用class RegEx,它是對(duì)模板代碼的高層次包裝,它為那些使用不到庫(kù)的整個(gè)功能的人提供了簡(jiǎn)單的接口,當(dāng)然它僅支持窄字符(narrow character)和“擴(kuò)展”的正則表達(dá)式語(yǔ)法。 對(duì)于想兼容POSIX的人可以使用POSIXAPI函數(shù):regcomp,regexec,regfree,regerror,這些對(duì)narrow character和Unicode都適用。
最后注意,這個(gè)庫(kù)現(xiàn)在支持運(yùn)行時(shí)本地化(run-time localization),它能完全識(shí)別POSIX正則表達(dá)式語(yǔ)法,包括一些多字符的元素比較和同等類型的高級(jí)特性,它還能兼容其它一些正則表達(dá)式庫(kù)包括GNU、BSD4的regex包。
安裝和配置
首先當(dāng)你從zip文件解壓本庫(kù)時(shí)必須保留它的內(nèi)部結(jié)構(gòu),如果你沒(méi)這樣做,那只好刪除你解壓的文件,重現(xiàn)來(lái)一次。 由于支持大多數(shù)常見(jiàn)的編譯器/標(biāo)準(zhǔn)庫(kù)/平臺(tái),這個(gè)庫(kù)不需要作使用前的配置。如果你碰到配置問(wèn)題,或想測(cè)試你的編譯器的配置信息,可以參考 配置文檔(這和boost的其它所有的庫(kù)的處理過(guò)程都一樣)。
由于本庫(kù)混合了模板代碼(頭文件中)和靜態(tài)代碼數(shù)據(jù)(cpp文件中),所以在你使用之前,必須將庫(kù)支持的代碼 生成到庫(kù)內(nèi)和檔案文件中。以下是幾個(gè)具體平臺(tái)的操作步驟: Borland C++ Builder 略 Microsoft Visual C++ 6 and 7 如果你使用VC5,你可能要找一下本庫(kù)的以前版本。 打開(kāi)命令提示符(其MSVC環(huán)境變量必須已定義,如果沒(méi)有可運(yùn)行Vcvars32.bat,位于<VC6>\bin),進(jìn)入<boost>\libs\regex\build 目錄 選擇正確的makefile,VC6++的是vc6.mak,支持STLPort的是vc6-stlport.mak 如下調(diào)用 nmake -fvc6.mak 如果想在VC6子目錄包含所有的lib、dll文件,lib文件拷在<VC6>\lib,dll文件拷在<VC6>\bin,可使用 nmake -fvc6.mak install 刪除生成過(guò)程中所有的臨時(shí)文件,可使用 nmake -fvc6.mak clean
最后只需添加<boost>根目錄到你的工程所包含的目錄列表中。沒(méi)有必要手動(dòng)將*.lib文件加到工程中,因?yàn)樵陬^文件會(huì)選擇正確的.lib文件。 注意:如果想靜態(tài)地鏈入regex庫(kù),可定義BOOST_REGEX_STATIC_LINK(在release版中生效)。 如果想直接使用源文件,可定義BOOST_REGEX_NO_LIB,這樣自動(dòng)選擇庫(kù)將失效。
1.簡(jiǎn)介出處:http://www.boost.org/libs/regex/doc/introduction.html 2.Koening
lookup:When a function is called, in order to determine if that
function is visible in the current scope, the namespaces in which the
functions parameters reside must be taken into account.
|