zoukankan      html  css  js  c++  java
  • !!!GRETA正则表达式模板类库

    http://www.vckbase.com/document/viewdoc/?id=1138

     GRETA的匹配速度比boost(http://www.boost.org)正则表达式库大约快7倍,比ATL7的CATLRegExp快10倍之多!

    GRETA正则表达式模板类库


    编译:胡金山

    下载源代码

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

      

    1. 正则表达式语法
    字符元 意义
    . 匹配单个字符
    [ ] 指定一个字符类,匹配方括号内的任意字符。例:[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"等。

    *

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

     

     

       2。 缩写匹配

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


    ATL CATLRegExp
      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\"\n", 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

     

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

  •  " 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+)(\\.(\\d\\d))?" );      // 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 MSVC6sp3istream& getline(istream& is, std::string& s){   s.erase();   char c = is.get();   while(c != ''''\n'''')   {      s.append(1, c);      c = is.get();   }   return is;}#endifint 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;}
  • 相关阅读:
    Balanced Binary Tree
    Convert Sorted List to Binary Search Tree
    Convert Sorted Array to Binary Search Tree
    Binary Tree Zigzag Level Order Traversal
    Validate Binary Search Tree
    Binary Tree Level Order Traversal II
    Binary Tree Level Order Traversal
    Maximum Depth of Binary Tree
    如何把U盘的两个盘或者多个盘合成一个
    bugku 想蹭网先解开密码
  • 原文地址:https://www.cnblogs.com/carl2380/p/1916010.html
Copyright © 2011-2022 走看看