如何编译重贪模式?

时间:2015-01-20 07:46:31

标签: python regex

import re

s = "{'key': 1234}{'test': {xyz}123}"

regex = re.compile("{.+?}")

result = regex.findall(s)

print result

结果是["{'key': 1234}", "{'test': {xyz}"]
但我希望结果是["{'key': 1234}", "{'test': {xyz}123"]
所以,将re.compile("{.+?}")更改为re.compile("{.+}")
现在的结果是["{'key': 1234}{'test': {xyz}123}"]
但我不希望。

1 个答案:

答案 0 :(得分:1)

我建议你改变你的正则表达式,

>>> s = "{'key': 1234}{'test': {xyz}123}"
>>> re.findall(r'\{(?:\{[^{}]*}|[^{}])*}', string)
["{'key': 1234}", "{'test': {xyz}123}"]

贪婪和非贪婪的正则表达式的问题。

>>> re.findall(r'\{.*}', s)
["{'key': 1234}{'test': {xyz}123}"]

此处.*是贪婪的,它会尽可能地匹配所有字符,直到最后}。所以匹配是从第一个{到最后一个}符号。所以你得到了上面的输出。

>>> re.findall(r'\{.*?}', s)
["{'key': 1234}", "{'test': {xyz}"]

此处.*?将进行非贪婪的匹配。因此,从{符号开始,它匹配第一个结束括号}之前的所有字符。所以你得到了上面的输出。

<强>解决方案:

\{(?:\{[^{}]*}|[^{}])*}
  • \{与文字{符号相匹配。

  • (?:..)被称为非捕获组。

  • \{[^{}]*}|[^{}]表示匹配{....}|任何字符,但不匹配{}[^{}]),

  • (?:\{[^{}]*}|[^{}])*零次或多次。也就是说,一旦角色不匹配,改变有助于来回切换。如果第一个模式与角色不匹配,那么下一个模​​式将会出现并尝试匹配。如果两者都不匹配,则控件转移到下面的}模式,因为我们将非捕获组定义为重复零次或多次。

  • }匹配文字结束括号。