是否有 Python 等效于正则表达式的 Perl "/x" 修饰符?

Posted

技术标签:

【中文标题】是否有 Python 等效于正则表达式的 Perl "/x" 修饰符?【英文标题】:Is there a Python equivalent to the Perl "/x" modifier for regular expressions? 【发布时间】:2022-01-13 01:49:22 【问题描述】:

Perl 使得使用/x 修饰符构造readable regular expressions 变得很容易。此修饰符允许编写正则表达式字符串并忽略这些字符串中的所有空格。换句话说,正则表达式的逻辑部分可以用空格甚至回车分隔,从而提高可读性。在 Python 中,我看到的唯一方法是构造这样的正则表达式字符串,在中间步骤中从中删除空格,然后使用生成的字符串进行匹配。有没有更优雅的方式来做到这一点?

【问题讨论】:

我不知道任何没有扩展修饰符的普通引擎。考虑到所有事情,您都需要一个自动执行压缩/扩展的正则表达式格式化程序。这是一个很好的regexformat.com。他们将在下周发布具有内联测试和令人难以置信的宏功能的版本 5。 请注意,任何支持修饰符的引擎通常都支持它们'inline',因此对于扩展模式,正则表达式字符串的第一个字符将是修饰符构造"(?x) .."。修饰符可以在任何地方。阅读修饰符,拯救你的大脑。 @sln 感谢您的评论。我已经开始明白你的意思了。 @sln Python 要求在开头插入(?x)(空格除外)。如果稍后插入,则行为未定义。 【参考方案1】:

是的,通过设置re.X / re.VERBOSE flag:

此标志允许您编写看起来更好的正则表达式。模式中的空格会被忽略,除非在字符类中,或者前面有未转义的反斜杠,或者在 *?(?:(?P<...> 等标记内。当一行包含一个不在字符类中且前面没有未转义的反斜杠的 # 时,从最左边的 # 到行尾的所有字符都将被忽略。

这意味着以下两个匹配十进制数的正则表达式对象在功能上是相等的:

a = re.compile(r"""\d +  # the integral part
                   \.    # the decimal point
                   \d *  # some fractional digits""", re.X)
b = re.compile(r"\d+\.\d*")

这与/x Perl 标志非常相似。

您可以在(?x:...)(启用)和(?-x:...)(禁用)分组内控制模式的一个小节中的相同标志。

【讨论】:

我还要指出,至少对于文档中的示例,您可以将每一行设为一个独立的字符串,并将它们连接在一起,允许您使用标准 Python cmets,这可以说是更明显的阅读。 @SilasRay:我不同意;你必须引用你想在周围放置空格的每个 sn-p。请注意,\d+ 之间有一个空格。 因此我说“可以说”。 ;) 就我个人而言,我觉得它更清晰,但这可能是因为我通常使用具有颜色代码格式的编辑器,因此如果字符串和 cmets 是真正的 Python cmets/strings,我会更清楚地突出它们。【参考方案2】:

要添加,内联修饰符可以放置在正则表达式中,以在给定表达式上强制执行相关匹配行为。在 Python 中,内联修饰符适用于整个正则表达式,不支持 inline negate 修饰符,例如 (?-ismx)

pattern = re.compile(r'''
                       (?x) 
                        \d+ (?# Some numbers)
                        \s+ (?# Whitespace)
                        \d+ (?# More numbers)
                      ''');

解决方法是导入 Python 的 regex 模块,其中内联修饰符应用于组或模式的末尾,并且可以打开或关闭它们。

import regex
pattern = regex.compile(r'(?x)  \d+  (?-x)[a-z]+(?x)   \d+', regex.V1)

【讨论】:

考虑到re.compile() 的用法,引擎是否会在(?x) 之前看到一堆文字空白,还是会追溯影响整个正则表达式?

以上是关于是否有 Python 等效于正则表达式的 Perl "/x" 修饰符?的主要内容,如果未能解决你的问题,请参考以下文章

python:非正则表达式等价于 re.findall

perl 之 正则表达式 (简)

是否有与 Perl 的 WWW::Mechanize 等效的 PHP?

是否有与 Java 正则表达式中的交集 (&&) 运算符等效的 JavaScript 正则表达式?

C# 等效于 Java 标点正则表达式

Python 等效于 Perl 的 HTTP::Async->next_response