轉載:www.csdn.net中,由於ATL Server的需要,需要對Client發送過來的地址、命令等複雜文字欄位資訊解碼,而Regex是公認的最強大的文字解析工具,所以,ATL提供了一些用於Regex的庫方便了我們的工作。
ATL1、 CATLRegExp類聲明:template <class CharTraits=CAtlRECharTraits>class CAtlRegExp; 初始化:與微軟的GRETA類庫(微軟研究院推出的另一個Regex類庫)不同,CATLRegExp並沒有在建構函式中提供初始化匹配字串的方法,而是讓使用者通過調用它的Parse()方法,使用Regex字串作為參數,就可以構造出一個我們所需要的用於匹配的類,例如我們需要匹配一種時間格式,可以是h:mm、也可以是hh:mm,那麼我們可以這樣構造我們的CAtlRegExp類: CAtlRegExp <> re;re.Parse( "{[0-9]?[0-9]}:{[0-9][0-9]}" ); ATL的Regex文法和Perl的Regex文法大同小異,不過有一個值得注意的地方就是ATL中用大括弧({ })表示其匹配字串中的Group,我們上面的運算式中,就聲明了2 個Group,一個是[0-9]?[0-9],另一個是[0-9][0-9]。
匹配:
調用CATLRegExp的Match()方法,就可以用該類來進行匹配了,Match方法的原型如下: BOOL Match(const RECHAR *szIn, CAtlREMatchContext<CharTraits> *pContext, const RECHAR **ppszEnd=NULL)參數的含義很明顯,不過需要注意到第一個參數的型別是:const RECHAR * szIN,是一個 const指標,這表明我們可以方便得使用std::string類的c_str()方法給其傳遞參數。
Match的結果通過第二個參數pContext所指向的CAtlREMatchContext<>類來返回,Match 的結果及其相關資訊都被存放在CAtlREMatchContext類中,我們只要訪問CAtlREMatchContext的方法和成員就可以得到匹配的結果。
2、 CAtlREMatchContext類 聲明:template <class CharTraits=CAtlRECharTraits>class CAtlREMatchContext使用: CAtlREMatchContext通過m_uNumGroups成員以及GetMatch()方法向調用者提供匹配的結果資訊。m_uNumGroups代表匹配上的Group有多少組,GetMatch()則根據傳遞給它的Group
的Index值,返回匹配上的字串的pStart和pEnd指標,調用者有了這兩個指標,自然可以很方便的得到匹配結果。3、 一個小樣本下面這個例子來源於MSDN,示範了CATLRegExp和CAtlREMatchContext類的典型使用方法:#include "stdafx.h"#include <atlrx.h> int main(int argc, char* argv[]){ CAtlRegExp<> reUrl; // five match groups: scheme, authority, path, query, fragment REParseError status = reUrl.Parse( "({[^:/?#]+}:)?(//{[^/?#]*})?{[^?#]*}(?{[^#]*})?(#{.*})?" ); if (REPARSE_ERROR_OK != status) { // Unexpected error. return 0; } CAtlREMatchContext<> mcUrl; if (!reUrl.Match( "http://search.microsoft.com/us/Search.asp?qu=atl&boolean=ALL#results", &mcUrl)) { // Unexpected error. return 0; } for (UINT nGroupIndex = 0; nGroupIndex < mcUrl.m_uNumGroups; ++nGroupIndex) { const CAtlREMatchContext<>::RECHAR* szStart = 0; const CAtlREMatchContext<>::RECHAR* szEnd = 0; mcUrl.GetMatch(nGroupIndex, &szStart, &szEnd); ptrdiff_t nLength = szEnd - szStart; printf("%d: /"%.*s/"/n", nGroupIndex, nLength, szStart); }}Output 0: "http"
1: "search.microsoft.com"
2: "/us/Search.asp"
3: "qu=atl&boolean=ALL"
4: "results"例子中所用的Regex為:({[^:/?#]+}:)?(//{[^/?#]*})?{[^?#]*}(?{[^#]*})?(#{.*})?以()為分界標誌,共分成5組,第一組是{[^:/?#]+}:,^是“非”後面成員的意思,那麼也就是說第一組從開頭開始,一直到:、/、?、#其中任何一個結束。聯絡後面的待匹配字串就可以得出所匹配的結果是http。4、 自訂匹配字串的縮寫形式為了方便,ATL已經幫我們定義了一些經常用到的Regex的簡略形式。例如:/d代表([0-9])、/n代表(/r|(/r?/n))等。這些縮寫形式都體現在CAtlRECharTraitsA/CAtlRECharTraitsW等類中,把這些類作為模板參數傳遞給CATLRegExp和 CAtlREMatchContext,我們就可以定義自己的匹配字串縮寫了。class CAtlRECharTraitsA{ static const RECHARTYPE** GetAbbrevs() { static const RECHARTYPE *s_szAbbrevs[] = { "a([a-zA-Z0-9])", // alpha numeric "b([ //t])", // white space (blank) "c([a-zA-Z])", // alpha "d([0-9])", // digit "h([0-9a-fA-F])", // hex digit "n(/r|(/r?/n))", // newline "q(/"[^/"]*/")|(/''''[^/'''']*/'''')", // quoted string "w([a-zA-Z]+)", // simple word "z([0-9]+)", // integer NULL }; return s_szAbbrevs; }};以上是atlrx.h摘錄下來的代碼,可以很清楚地看到ATL是通過一個GetAbbrevs()函數來定義字串縮寫的。要定義新的縮寫形式,我們只需要這樣: class MyRegTraits : public ATL::CAtlRECharTraitsA{public: static const RECHARTYPE** GetAbbrevs() { static const RECHARTYPE *s_szAbbrevs[] = { "a([a-zA-Z0-9])", // alpha numeric "b([ //t])", // white space (blank) "c([a-zA-Z])", // alpha "d([0-9])", // digit "h([0-9a-fA-F])", // hex digit "n(/r|(/r?/n))", // newline "q(/"[^/"]*/")|(/''''[^/'''']*/'''')", // quoted string "w([a-zA-Z]+)", // simple word "z([0-9]+)", // integer "e([0-8]+)", //自己添加 NULL }; return s_szAbbrevs; } };讓我們自己定義的Trait類繼承自CAtlRECharTraitsA,然後改寫GetAbbrevs()函數,增加 一些需要的簡寫就可以被使用了。下面的程式碼範例了使用了我們自己的類中定義的“/e”簡 略表達: int main ( ){ ATL::CAtlRegExp < MyRegTraits > re ; re.Parse( "//e+" ); ATL::CAtlREMatchContext < MyRegTraits > mc ; BOOL res1 = re.Match( "678", &mc ); // returns TRUE: successful match res1 = re.Match ( "999" , &mc ) ; // returns FALSE:match fail}只要在構造ATL::CAtlRegExp和 ATL::CAtlREMatchContext類時,傳遞過去我們的 MyRegTraits類作為Traits的參數,就可以直接使用自己定義的簡略符號了。
5、 結尾
雖然現在C++的社區裡已經擁有了Boost::regex,GRETA等非常著名的Regex庫,可是 作為VC++內建的模板庫,ATL中的Regex庫仍然給我們的工作提供了極大的便利。由於 ATL是微軟官方發布的Library,所以它擁有良好的文檔說明、嚴格的測試以及微軟官方的 支援人員。另外在用ATL開發COM組件的時候,更可以方便地利用正則庫的巨大威力。
由於本人學識所限,文章內容錯在所難免,如有批評指正之詞,請mail :firingme@sina.com