【问题标题】:Converting C++ Boost Regexes to Python re regexes [closed]将 C++ Boost 正则表达式转换为 Python 正则表达式 [关闭]
【发布时间】:2015-12-02 17:00:30
【问题描述】:

目的是将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 正则表达式转换为 Python
  • boost regex 和 python re regex 有什么区别?

C++ boost::u32regex 是否与 python 中的 re 正则表达式相同? 如果不是,有什么区别? (文档的链接将不胜感激=))例如:

  • 在boost中,有boost::u32regex_match,是一样的吗 re.match?
  • boost里面有boost::u32regex_search,和re.search有什么区别
  • 还有boost::format_perlboost::match_defaultboost::smatch,它们在pythonre中的等价物是什么?

【问题讨论】:

  • 请注意 [!-+] 匹配 !, ", #, $, %, &amp;, ', (, @87654348@, @, *+rulere 正则表达式)。这里的所有正则表达式在 Python 中的工作方式都是一样的。如果您有更复杂的模式,请分享。 re.matchregex_match 不同,因为 re.match 在字符串开头寻找匹配,而 regex_match 需要完整的字符串匹配。 regex_search 的行为与 regex_search 相同。您可以将$ 锚添加到与regex_match 一起使用的模式中,并将它们传递给re.match。没有 boost::format_perlboost::match_default 标志。匹配是finditer
  • 其实就是从这个.cpp代码:gist.github.com/alvations/99354d0fbe294c14cf7f,用来从这个软件moin.delph-in.net/ReppTop读取一系列.rpp文件:dropbox.com/s/ppgglwvwz16hlt1/erg.zip?dl=0。我们正在尝试移植此 python。
  • 我的建议是不要尝试在 Python re 中进行这项工作。请改用regex 包。在要点中,我看到输入被解释为正则表达式。用户输入的正则表达式可能会使用 Boost 中的高级功能,这在 Python re 中可能不可用。此外,如果您正在处理 Unicode,则应该使用 Python 3.3+。至于剩下的问题,太宽泛了。
  • regex_search 的行为与 regex_search 应为 regex_search 的行为为 re.search。我同意 nhahtdh 的观点,即这个问题很广泛,而且由于您没有共享所有的正则表达式,所以也不清楚(不知道它们有多复杂,以及它们是否可以按原样移植到 Python)。经验法则是不要盲目地在另一种语言中使用一种语言代码。
  • 用于提升 Unicode (ICU) 正则表达式。使用 make_u32regex 的唯一原因是使用 ICU 属性库。在这种情况下,所有道路都通向 utf-32,无论输入正则表达式和主题编码是 utf8/16/32 是什么。对于宏语言,默认的 Unicode 内部编码通常是 utf-8,并且它们提供了自己的 Unicode 属性版本。所以,这些都不应该是一个问题。 可能的唯一问题是将任何特殊的 boost 构造转换为标准化形式。这可能意味着整理元素或其他元素。

标签: python c++ regex boost


【解决方案1】:

如何将 C++ boost 正则表达式转换为 Python

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

boost正则表达式和pythonre正则表达式有什么区别?

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

此外,与在 Boost 中一样,您不必在字符类内转义 [,在字符类外转义 {

\1 之类的反向引用与 Python 中的相同。

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

注意命名组定义的区别:Boost 中的 (?&lt;NAME&gt;expression)/(?'NAME'expression) 和 Python 中的 (?P&lt;NAME&gt;expression)

我看到您的正则表达式主要属于“简单”类别。最复杂的模式是tempered greedy token(例如⌊-((?:(?!-⌋).)*)-⌋)。要优化它们,您可以使用 unroll the loop 技术,但可能没有必要,具体取决于您使用表达式处理的文本大小。

在我看来,最麻烦的部分是您大量使用 Unicode 文字。在 Python 2.x 中,所有字符串都是字节数组,您必须始终确保将 unicode 对象传递给 Unicode 正则表达式(请参阅Python 2.x’s Unicode Support)。在 Python 3 中,默认情况下所有字符串都是 UTF8,您甚至可以在源代码中使用 UTF8 文字字符而无需任何额外操作(请参阅Python’s Unicode Support)。因此,Python 3.3+(支持原始字符串文字)是一个不错的选择。

现在,关于剩下的问题:

boost里面有boost::u32regex_match,和re.match一样吗?

re.match 与 regex_match 不同,因为re.match 正在寻找匹配字符串开头的,而regex_match 需要完整的字符串匹配。但是,在 Python 3 中,您可以使用与 Boost regex_match 等效的 re.fullmatch(pattern, string, flags=0)

boost里面有boost::u32regex_search,和re.search有什么区别

当您需要在字符串中的任何位置查找匹配项时,您需要使用re.search(请参阅match() versus search())。因此,此方法提供了与 Boost 中的 regex_search 类似的功能。

还有boost::format_perlboost::match_defaultboost::smatch,它们在python中的等价物re是什么?

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

最后,必读文章Python’s re Module

【讨论】:

  • 感谢您的全面回答!!!看完信息我还在消化=)
猜你喜欢
  • 2014-11-08
  • 1970-01-01
  • 2011-10-02
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
  • 2015-09-26
相关资源
最近更新 更多