介绍 ATL CAtlRegExp,GRETA,Boost::regex 等正则表达式库

本文摘要翻译了几篇文章的内容,简单介绍 ATL CAtlRegExp,GRETA,Boost::regex 等正则表达式库,这些表达式库使咱们能够方便地利用正则库的巨大威力,给咱们的工做提供了便利。

  正则表达式语法ios

字符元 意义 . 匹配单个字符 [ ] 指定一个字符类,匹配方括号内的任意字符。例:[abc] 匹配 "a", "b"或 "c"。 ^ 若是^出如今字符类的开始处,它否认了字符类,这个被否认的字符类匹配除却方括号内的字符的字符。如:[^abc]匹配除了"a", "b"和"c"以外的字符。若是^出如今正则表达式前边,它匹配输入的开头,例:^[abc]匹配以"a", "b"或"c"开头的输入。 - 在字符类中,指定一个字符的范围。例如:[0-9]匹配"0"到"9"的数字。 ? 指明?前的表达式是可选的,它能够匹配一次或不进行匹配。例如: [0-9][0-9]? 匹配"2"或"12"。 + 指明?前的表达式匹配一次或屡次。例如:[0-9]+匹配"1", "13", "666"等。

  *git

指明*前的表达式匹配零次或屡次。 ??, +?, *? ?, +和*的非贪婪匹配版本,它们尽量匹配较少的字符;而?, +和*则是贪婪版本,尽量匹配较多的字符。例如:输入"<abc><def>", 则<.*?> 匹配"<abc>",而<.*>匹配"<abc><def>"。 ( ) 分组操做符。例如:(d+,)*d+匹配一串由逗号分开的数字,例如: "1"或"1,23,456"。 转 义字符,转义紧跟的字符。例如,[0-9]+ 匹配一个或多个数字,而 [0-9]+ 匹配一个数字后跟随一个加号的状况。反斜杠也用于表示缩写,a 就表示任何数字、字母。若是后紧跟一个数字n,则它匹配第n个匹配群组(从0开始),例如,<{.*?}>.*?</>匹配 "<head>Contents</head>"。注意,在C++字符串中,反斜杠须要用双反斜杠来表示: "+", "a", "<{.*?}>.*?</ >"。 $ 放在正则表达式的最后,它匹配输入的末端。例如:[0-9]$匹配输入的最后一个数字。 | 间隔符,分隔两个表达式,以正确匹配其中一个,例如:T|the匹配"The" 或"the"。

  

  缩写匹配正则表达式

缩写 匹配 a 字母、数字([a-zA-Z0-9]) 空格(blank): ([ ]) c 字母([a-zA-Z]) d 十进制数 ([0-9]) h 十六进制数([0-9a-fA-F]) 换行: ( |( ? )) q 引用字符串("[^"]*")|(''''[^'''']*'''') w 一段文字 ([a-zA-Z]+) z 一个整数([0-9]+)

  ATL CATLRegExpapp

  ATL Server经常须要对地址、命令等复杂文字字段信息解码,而正则表达式是强大的文字解析工具,因此,ATL提供了正则表达式解释工具。函数

  示例:工具

#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"
", nGroupIndex, nLength, szStart);
}
}   
输出: 0: "http"
1: "search.microsoft.com"
2: "/us/Search.asp"
3: "qu=atl&boolean=ALL"
4: "results"

   Match的结果经过第二个参数pContext所指向的CAtlREMatchContext类来返回,Match的结果及其相关信息都被存放在 CAtlREMatchContext类中,只要访问CAtlREMatchContext的方法和成员就能够获得匹配的结果。 CAtlREMatchContext经过m_uNumGroups成员以及GetMatch()方法向调用者提供匹配的结果信息。 m_uNumGroups表明匹配上的Group有多少组,GetMatch()则根据传递给它的Group的Index值,返回匹配上的字符串的 pStart和pEnd指针,调用者有了这两个指针,天然能够很方便的获得匹配结果。性能

  更多内容请参阅: CAtlRegExp Class测试

  GRETAui

  GRETA是微软研究院推出的一个正则表达式模板类库,GRETA 包含的 C++ 对象和函数,使字符串的模式匹配和替换变得很容易,它们是:this

  • " rpattern: 搜索的模式
  • " match_results/subst_results: 放置匹配、替换结果的容器
  •    为了执行搜索和替换的操做,用户首先须要用一个描述匹配规则的字符串来显式初始化一个rpattern对象,而后把须要匹配的字符串做为参数,调用 rpattern的函数,好比match()或者substitute(),就能够获得匹配后的结果。若是match()/substitute()调用 失败,函数返回false,若是调用成功,函数返回true,此时,match_results对象存储了匹配结果。请看例子代码:

    #include <iostream>
    #include <string>
    #include "regexpr2.h"
    using namespace std;
    using namespace regex;
    int main() {
    match_results results;
    string str( "The book cost $12.34" );
    rpattern pat( "$(d+)(.(dd))?" ); 
    // Match a dollar sign followed by one or more digits,
    // optionally followed by a period and two more digits.
    // The double-escapes are necessary to satisfy the compiler.
    match_results::backref_type br = pat.match( str, results );
    if( br.matched ) {
    cout << "match success!" << endl;
    cout << "price: " << br << endl;
    } else {
    cout << "match failed!" << endl;
    }
    return 0;
    }   
    程序输出将是: match success!
    price: $12.34

      您能够阅读GRETA文档,获知rpattern对象的细节内容,并掌握如何自定义搜索策略来获得更好的效率。

       注意:全部在头文件regexpr2.h里的声明都在名称空间regex之中,用户使用其中的对象和函数时,必须加上前缀"regex::",或者预先 "using namespace regex;" 一下,为了简单起见,下文的示例代码中将省略"regex::" 前缀。 做者生成了greta.lib和regexpr2.h文件,只需这两个文件的支持便可使用greta来解析正则表达式。

      匹配速度小议

       不一样的正则表达式匹配引擎擅长于不一样匹配模式。做为一个基准,当用模式:"^([0-9]+)(-| |$)(.*)$" 匹配字符串"100- this is a line of ftp response which contains a message string"时,GRETA的匹配速度比boost(http://www.boost.org)正则表达式库大约快7倍,比ATL7的 CATLRegExp快10倍之多! Boost Regex 的说明文档带有一个不少模式的匹配测试Performance结果。比较这个结果后,我发现GRETA在大部分状况下和Boost Regex性能差很少,可是在用Visual Studio.Net 2003编译的状况下,GRETA还略胜一筹。

      Boost.Regex

      Boost提供了boost::basic_regex来支持正则表达式。boost::basic_regex的设计很是相似std::basic_string:

    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;
    }   
       Boost Regex 库附带的文档很是丰富,示例更是精彩,好比有两个例子程序,很少的代码,程序就能够直接对 C++ 文件进行语法高亮标记,生成相应的 HTML (converts a C++ file to syntax highlighted HTML)。下面的例子能够分割一个字符串到一串标记符号(split a string into tokens)。 #include <list> #include <boost/regex.hpp> unsigned tokenise(std::list<std::string>& l, std::string& s) { return boost::regex_split(std::back_inserter(l), s); } #include <iostream> using namespace std; #if defined(BOOST_MSVC) || (defined(__BORLANDC__) && (__BORLANDC__ == 0x550)) // problem with std::getline under MSVC6sp3 istream& getline(istream& is, std::string& s) { s.erase(); char c = is.get(); while(c != '''' '''') { s.append(1, c); c = is.get(); } return is; } #endif int main(int argc) { string s; list<string> l; do{ if(argc == 1) { cout << "Enter text to split (or "quit" to exit): "; getline(cin, s); if(s == "quit") break; } else s = "This is a string of tokens"; unsigned result = tokenise(l, s); cout << result << " tokens found" << endl; cout << "The remaining text is: "" << s << """ << endl; while(l.size()) { s = *(l.begin()); l.pop_front(); cout << s << endl; } }while(argc == 1); return 0; }
    相关文章
    相关标签/搜索