将C ++ Boost正则表达式转换为Python re rexx

时间:2015-12-02 17:00:30

标签: python c++ regex boost

目的是将C++ boost中的这些正则表达式转换为Python re正则表达式:

  typedef boost::u32regex tRegex;

  tRegex emptyre = boost::make_u32regex("^$");
  tRegex commentre = boost::make_u32regex("^;.*$");
  tRegex versionre = boost::make_u32regex("^@\\$Date: (.*) \\$$");
  tRegex includere = boost::make_u32regex("^<(\\S+)$");
  tRegex rungroupre = boost::make_u32regex("^>(\\d+)$");
  tRegex readreppre = boost::make_u32regex("^>(\\S+)$");
  tRegex tokre = boost::make_u32regex("^:(.*)$");
  tRegex groupstartre = boost::make_u32regex("^#(\\d+)$");
  tRegex groupendre = boost::make_u32regex("^#$");
  tRegex rulere = boost::make_u32regex("^([!-+^])([^\\t]+)\\t+([^\\t]*)$");

我可以一个接一个地重写这些正则表达式但是上面的例子还有很多,所以我的问题是关于

  • 如何将C ++ boost regexest转换为Python
  • boost regexes和python re rexx之间有什么区别?

C ++ boost::u32regex与python中的re正则表达式相同吗?如果没有,有什么区别? (非常感谢文档的链接=))例如:

  • 在提升中,有boost::u32regex_match,就像是一样 re.match
  • 在提升中,有boost::u32regex_search,与re.search有什么不同
  • 还有boost::format_perlboost::match_default以及boost::smatch,它们在python re中的等效性是什么?

1 个答案:

答案 0 :(得分:2)

  

如何将C ++ boost regexest转换为Python

如果是简单的正则表达式,例如\w+\s+\d+>.*$,则无需更改模式。如果使用下面提到的构造更复杂的模式,您很可能必须重新编写正则表达式。与从一种风味/语言到另一种风味/语言的任何转换一样,一般的答案是不要。但是,Python和Boost确实有一些相似之处,特别是当涉及简单模式(如果Boost使用类似PCRE的模式)包含点(a.*b),常规([\w-]*)和否定({ {1}})字符类,常规量词,如[^>]* / + / *等。

  

提升正则表达式和python ?正则表达式之间有什么区别?

Python re module 并不像 Boost regexps 那样丰富(足以提及\h, \G, \K, \R, \X, \Q...\E, branch reset, recursion, possessive quantifiers, POSIX character classes and character properties,{{3}等结构}),以及Boost的其他功能。 re仅限于Python中的整个表达式,而不是其中的一部分,因此您应该知道(?imsx-imsx:pattern)中的(?i)将被视为处于开头的&amp;|&#((?i)x26);|&#38;模式(但是,它对此表达式没有任何影响)。

此外,与Boost相同,您不必在角色类中转义[,在角色类外转义{

\1这样的反向引用与Python相同。

由于你没有在你的模式中交替使用捕获组(例如re.sub(r'\d(\w)|(go\w*)', '\2', 'goon')),所以应该没有问题(在这种情况下,Python不会用任何值填充非参与组,并返回一个空的结果)。

请注意命名组定义的差异:Boost中的(?<NAME>expression) / (?'NAME'expression)和Python中的(?P<NAME>expression)

我认为你的正则表达式主要属于“简单”类别。最复杂的模式是extended replacement pattern(例如⌊-((?:(?!-⌋).)*)-⌋)。要优化它们,您可以使用 tempered greedy token 技术,但根据您使用表达式处理的文本大小,可能没有必要。

我认为最棘手的部分是你大量使用Unicode文字。在Python 2.x中,所有字符串都是字节数组,您必须始终确保将unicode对象传递给Unicode regexp(请参阅unroll the loop)。在Python 3中,默认情况下所有字符串都是UTF8,您甚至可以在源代码中使用UTF8文字字符而无需任何其他操作(请参阅Python 2.x’s Unicode Support)。因此,Python 3.3+(支持原始字符串文字)是一个很好的选择。

现在,至于剩下的问题:

  

在提升中,有boost::u32regex_match,与re.match相同吗?

Python’s Unicode Support 与regex_match不同,因为re.match正在寻找 在字符串开头 < / strong>,re.match要求 完整字符串匹配 。但是,在Python 3中,您可以使用等同于Boost regex_match regex_match

  

在提升中,有boost::u32regex_search,它与re.search

有什么不同

当您需要在字符串中的任何位置找到匹配项时,您需要使用re.search(请参阅re.fullmatch(pattern, string, flags=0))。因此,这种方法提供了类似于match() versus search()在Boost中的功能。

  

还有boost::format_perlboost::match_default以及boost::smatch,它们在python re中的等价性是什么?

Python不支持类似Perl的表达式,Boost可以,Python re模块只是一个“修剪”的Perl正则表达式引擎,它没有我前面提到的很多很好的功能。因此,在那里找不到像defaultperl这样的标志。至于smatch,您可以使用 regex_search 来获取所有re.finditermatch objects返回所有匹配(或仅在指定捕获组时为子匹配)作为元组的字符串/列表的列表。请参阅re.findall

在结论中,必读的文章re.findall/re.finditer difference