如何嵌套"("在python正则表达式中工作

时间:2015-09-29 11:02:03

标签: python regex nested

我正在尝试提取 (...) 中的值,这些值可能是也可能不是多行。我在正则表达式中使用 "嵌套(" 。但它没有按预期工作。为简单起见,我将正则表达式更改为下面;

代码段供您参考;

RE_MULTI_LINE_PARAMS = ".*"
RE_M_DECLERATION = r"\(%s\)"%RE_MULTI_LINE_PARAMS
...
# read file
fh = open(fname)
fcontent = fh.read()
patternList = re.findall(RE_M_DECLERATION, fcontent, re.VERBOSE)
print patternList

在其他情况下,我使用;

RE_MULTI_LINE_PARAMS = "(.*)"

上面的其余代码。但我看到结果列表中存在差异。

可能有人可以解释,"为什么会表现出来?" so或"嵌套括号如何在正则表达式中起作用?"

1 个答案:

答案 0 :(得分:1)

  

我正在尝试提取(...)中的值,这些值可能是多线也可能不是。

如果希望.*能够包含换行符,则需要使用flags = re.DOTALL。

  

我在结果列表中看到了不同。

请参阅findall documentation

  

如果模式中存在一个或多个组,则返回组列表;如果模式有多个组,这将是一个元组列表。

在正则表达式中添加组时,它只返回内部组的文本。即,不包括括号。如果不包含组,则返回匹配的全文,包括括号。

好吧,这听起来不太清楚,所以我会稍微扩展一下。在正则表达式中使用()时,您是正确的,它不会更改正则表达式将匹配的字符串。括号的作用是识别将在编号的“组”中捕获的匹配的部分。因此,您的两个示例都会找到相同数量的匹配项。 然而,在找到匹配后,findall具有不同的行为,具体取决于是否定义了任何组。如果您只定义了一个组,则返回该组的内容而不是整个匹配。 例如:

>>> import re
>>> a = re.compile(r'\(.*?\)')
>>> b = re.compile(r'\((.*?)\)')
>>> s = 'one (two) three (four) five'
>>> a.findall(s)
['(two)', '(four)']
>>> b.findall(s)
['two', 'four']

两个正则表达式都匹配相同的字符串:

>>> [match.group(0) for match in a.finditer(s)]
['(two)', '(four)']
>>> [match.group(0) for match in b.finditer(s)]
['(two)', '(four)']

但是其中一个人有一个选择字符串部分的捕获组:

>>> [match.groups() for match in b.finditer(s)]
[('two',), ('four',)]
>>> [match.groups() for match in a.finditer(s)]
[(), ()]

除了这些问题之外,您会发现.*尽可能匹配。因此,对于字符串"one (two) three (four)",您不会在twofour上获得匹配,而是在two) three (four上获得匹配。你可以使用像.*?这样的非贪婪匹配,或者尝试匹配非括号,例如类似于[^)]*