Python正则表达式:最新版本中的匹配圆括号(2019年2月)

2024-04-26 02:45:44 发布

您现在位置:Python中文网/ 问答频道 /正文

1.关于Python regex 2019.02.21

Python正在升级regex模块。最新版本于2019年2月21日发布。您可以在此处查阅: https://pypi.org/project/regex/

它将及时替换re模块。现在,您需要使用pip install regex手动安装它,并导入regex模块而不是re

你知道吗 

2.新的regex特性

最新版本最酷的特性是递归模式。在这里阅读更多信息:https://bitbucket.org/mrabarnett/mrab-regex/issues/27

此功能允许查找匹配的括号( .. )或花括号{ .. }。下面的网页解释了如何做到这一点:https://www.regular-expressions.info/recurse.html#balanced 我引用:

The main purpose of recursion is to match balanced constructs or nested constructs. The generic regex is b(?:m|(?R))*e where b is what begins the construct, m is what can occur in the middle of the construct, and e is what can occur at the end of the construct. For correct results, no two of b, m, and e should be able to match the same text. You can use an atomic group instead of the non-capturing group for improved performance: b(?>m|(?R))*e.  

A common real-world use is to match a balanced set of parentheses. \((?>[^()]|(?R))*\) matches a single pair of parentheses with any text in between, including an unlimited number of parentheses, as long as they are all properly paired.

你知道吗 

3.我的问题

我正在试验匹配的花括号{ .. }。因此,我只需应用上面网页中的regex,但我将(替换为{。这给了我以下正则表达式:

{(?>[^{}]|(?R))*}

我在https://regex101.com上试了一下,得到了漂亮的结果

enter image description here

我想更进一步,找到一组特定的匹配花括号,如下所示:

MEMORY\s*{(?>[^{}]|(?R))*}

结果很好:

enter image description here

但当我尝试

SECTIONS\s*{(?>[^{}]|(?R))*}

什么也找不到。不匹配。MEMORY{..}SECTIONS{..}部分之间的唯一区别是后者有一些嵌套的花括号。所以问题应该在那里找到。但我不知道怎么解决这个问题


*注1:
https://regex101.com上,您可以选择regex的风格。通常我选择Python,但这次我选择了PCRE(PHP),因为regex101网站还没有应用最新的Python regexes升级。  
为了确认结果,我还在我的终端中的一个简单python会话中使用如下命令进行了尝试:
import regex
p = regex.compile(r"...")
text = """ ... """
p.findall(text)

*注2:
我用于测试的文本是:

MEMORY
{
    /* Foobar */
    consectetur adipiscing elit,
    sed do eiusmod tempor incididunt
}
Lorem ipsum dolor sit amet,

SECTIONS
{
    ut labore et dolore magna aliqua.
    /* Foobar */
        FOO
        {
            /* Foobar */
            Ut enim ad minim veniam,
            quis nostrud exercitation ullamco
        }

        BAR
        {
            /* Foobar */
            laboris nisi
            ut
        }
    aliquip ex ea commodo consequat.
}
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.


Tags: 模块ofthetotextinhttpsis
1条回答
网友
1楼 · 发布于 2024-04-26 02:45:44

使用(?R)构造递归整个模式,而只希望递归{...}子模式。用捕获组包装它,并用subroutine递归它:

p = regex.compile(r"SECTIONS\s*({(?>[^{}]|(?1))*})")
for m in p.finditer(text):
    print(m.group())

参见Python ^{} demo online

请注意,第一个模式也存在同样的问题,如果在其中添加嵌套的花括号,它将不起作用。将其固定为MEMORY\s*({(?>[^{}]|(?1))*})

相关问题 更多 >