python - Python中的Perl兼容正则表达式(PCRE)

标签 python regex parsing pcre

我必须在Python中基于PCRE解析一些字符串,而且我不知道该怎么做。

我想解析的字符串如下所示:

match mysql m/^.\0\0\0\n(4\.[-.\w]+)\0...\0/s p/MySQL/ i/$1/

在此示例中,我必须获得以下不同项:
"m/^.\0\0\0\n(4\.[-.\w]+)\0...\0/s" ; "p/MySQL/" ; "i/$1/"

我发现与Python中的PCRE操作有关的唯一内容是以下模块:http://pydoc.org/2.2.3/pcre.html(但它被编写为.so文件...)

您知道是否存在一些Python模块可以解析这种字符串吗?

最佳答案

在Python中特别小心非ASCII

Python如何处理模式和字符串中的非ASCII或无法处理非ASCII时,确实存在一些细微的问题。更糟糕的是,这些差异不仅取决于您使用的是哪个版本的Python,还取决于您是否具有“广泛的构建”。

总的来说,当您处理Unicode时,构建较宽的 Python 3效果最佳而构建较窄的Python 2效果最差,但与Perl正则表达式的工作方式相比,所有组合仍然相差甚远相对于Unicode。如果您要在Python中寻找ᴘᴄʀᴇ模式,则可能需要比旧的re模块更进一步。

令人讨厌的“广泛构建”问题终于被一劳永逸地修复了 -只要您使用足够高级的Python版本即可。这是the v3.3 release notes的摘录:

Functionality

Changes introduced by PEP 393 are the following:

  • Python now always supports the full range of Unicode codepoints, including non-BMP ones (i.e. from U+0000 to U+10FFFF). The distinction between narrow and wide builds no longer exists and Python now behaves like a wide build, even under Windows.
  • With the death of narrow builds, the problems specific to narrow builds have also been fixed, for example:
    • len() now always returns 1 for non-BMP characters, so len('\U0010FFFF') == 1;
    • surrogate pairs are not recombined in string literals, so '\uDBFF\uDFFF' != '\U0010FFFF';
    • indexing or slicing non-BMP characters returns the expected value, so '\U0010FFFF'[0] now returns '\U0010FFFF' and not '\uDBFF';
    • all other functions in the standard library now correctly handle non-BMP codepoints.
  • The value of sys.maxunicode is now always 1114111 (0x10FFFF in hexadecimal). The PyUnicode_GetMax() function still returns either 0xFFFF or 0x10FFFF for backward compatibility, and it should not be used with the new Unicode API (see issue 13054).
  • The ./configure flag --with-wide-unicode has been removed.


Python正则表达式的 future

与标准Python发行版的re库中当前可用的相比,Matthew Barnett’s regex module for both Python 2 and Python 3 alike在几乎所有可能的方式上都好得多,并且最终很可能会替换re。与您的问题特别相关的是,与现在的regex相比,他的re库在所有方面都更加more(即它与Perl兼容的更多),这将使您更容易将Perl regexes移植到Python。因为它是完全重写(例如从头开始,而不是在汉堡包中),所以它是在考虑非ASCII的情况下编写的,而re不是。

因此,regex库在如何处理事物方面更加遵循UTS#18: Unicode Regular Expressions的(当前)建议。如果不是全部,它在大多数情况下都达到或超过UTS#18 1级要求,这通常是您必须使用ICU regex库或Perl本身的东西;或者,如果您特别有勇气,则新Java 7更新了其regexes ,因为它也符合UTS#18的Level One requirements

除了满足这些第一级要求,这些要求对于基本的Unicode支持都是绝对必要的,但是pythont当前的re库未满足,令人敬畏的regex库也满足了RL2.5命名字符(\N{...})),RL2.2扩展的第二级要求。字素簇(\X)和来自revision 14 of UTS#18的“完整属性”上的新RL2.7。

Matthew的regex模块也可以进行Unicode大小写折叠,以便区分大小写的匹配在Unicode上可以可靠地工作,而re则不能。


以下不再是正确的,因为regex现在支持完整的Unicode大小写折叠,例如Perl和Ruby。

One super‐tiny difference is that for now, Perl’s case‐insensitive patterns use full string‐oriented casefolds while his regex module still uses simple single‐char‐oriented casefolds, but this is something he’s looking into. It’s actually a very hard problem, one which apart from Perl, only Ruby even attempts.



下充分casefolding,这意味着(例如)现在"ß"正确匹配"SS""ss""ſſ",当选择不区分大小写匹配"ſs"(等)。 (这在希腊语中比在拉丁语中更重要。)

另请参阅my third OSCON2011 talk的幻灯片或doc源代码,标题为“ Unicode支持大战:好,坏和(主要是)丑陋的”,以获取JavaScript,PHP,Go,Ruby,Python,Java,和Perl。如果无法使用Perl正则表达式或ICU正则表达式库(可惜没有命名捕获),那么Matthew的Python regex可能是您最好的选择。

NᴏᴛᴀBᴇɴᴇs.ᴠ.ᴘ。 (= s'il vousplaît等):Python regex库的作者实际上并未在下面放置未经请求的非商业性非广告。 :)

regex功能

Python regex库具有 super 功能的corntcopeia功能,其中一些功能在任何其他正则表达式系统中都找不到。无论您是偶然使用它来获得它的坚固性还是出色的Unicode支持,这些都非常值得一试。

该模块感兴趣的一些杰出功能包括:
  • 可变宽度在之后,该功能在正则表达式引擎中非常罕见,并且在您真正想要它时非常沮丧。这很可能是正则表达式中最常请求的功能。
  • 向后搜索,因此您不必自己先反转字符串。
  • 作用域内的ismx类型选项,以便(?i:foo)仅对foo进行大小写折叠,而不对整个字体进行折叠,或者(?-i:foo)仅对foo进行关闭。这就是Perl(或可以)的工作方式。
  • 基于编辑距离的模糊匹配(Udi Manber的agrepglimpse也具有)
  • 通过\L<list>内插隐式最短到最长排序的命名列表
  • 仅与单词的开头或结尾(而不是任一侧)匹配的元字符(\m\M)
  • 支持所有Unicode行分隔符(Java可以做到这一点,Perl可以做到,尽管每个RL1.6\R有点令人困惑。
  • 对每个RL1.3用括号括起来的字符类进行完整的运算(并集,交集,差和对称差),这比在Perl中轻松进行得多。
  • 允许重复捕获组,例如(\w+\s+)+,您可以在其中获得第一个组的所有单独匹配项,而不仅仅是最后一个匹配项。 (我相信C#也可以这样做。)
  • 比前行中的偷偷摸摸的捕获组更容易实现重叠的匹配。
  • 所有组的开始和结束位置,以便以后进行切片/子字符串操作,这与Perl的@+@-数组非常相似。
  • 通过(?|...|...|...|)进行分支重置的运算符,以在Perl中的工作方式重置每个分支中的组编号。
  • 可以配置为让您的咖啡在早上等您。
  • 支持RL2.3中更复杂的单词边界。
  • 默认情况下采用Unicode字符串,并且完全支持RL1.2a,以便\w\b\s等对Unicode起作用。
  • 支持字素的\X
  • 支持\G连续点断言。
  • 对于64位版本正确工作(re仅具有32位索引)。
  • 支持多线程。

  • 好的,这已经足够炒作了。 :)

    另一个很好的替代正则表达式引擎

    如果您是正则表达式怪胎,那么最后一个值得一看的替代方法是Russ Cox出色的Python library bindingsRE2 library。它还本地支持Unicode,包括简单的基于字符的大小写折叠,并且与re不同,它特别提供了Unicode通用类别和Unicode脚本字符属性,这是更简单的Unicode处理最常需要的两个关键属性。

    尽管RE2错过了一些Unicode特性,例如ICU,Perl和Python中的\N{...}命名字符支持,但它具有极其重要的计算优势,因此当您担心基于饥饿的拒绝-时,它成为的首选regt引擎。通过Web查询等中的正则表达式进行服务攻击。它通过禁止反向引用来管理此问题,这会导致正则表达式停止正常运行,并有可能在时间和空间上发生超指数爆炸。

    RE2的库绑定(bind)不仅适用于C/C++和Python,还适用于Perl,尤其是Go(适用于Go),后者打算很快替换那里的标准正则表达式库。

    关于python - Python中的Perl兼容正则表达式(PCRE),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7063420/

    相关文章:

    python - Python 中的异常是什么?

    python - 一大一小两个整数相除时得到错误答案

    java - 解析管道分隔的字符串

    regex - sed -n 中的多模式

    java - 如何在 Java 中将 XML 转换为 JSON 并避免解析器尝试将 String 解析为数字

    string - Makefile:返回字符串的前两个字符

    python:将两个文件作为一个文件对象打开

    python - Sklearn 管道 : Get feature names after OneHotEncode In ColumnTransformer

    javascript - 返回括号之间的文本且不包含括号

    javascript - $error.pattern 无法正常工作