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}"]
,
但我不希望。
答案 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}"]
此处.*?
将进行非贪婪的匹配。因此,从{
符号开始,它匹配第一个结束括号}
之前的所有字符。所以你得到了上面的输出。
<强>解决方案:强>
\{(?:\{[^{}]*}|[^{}])*}
\{
与文字{
符号相匹配。
(?:..)
被称为非捕获组。
\{[^{}]*}|[^{}]
表示匹配{....}
或|
任何字符,但不匹配{
或}
([^{}]
),
(?:\{[^{}]*}|[^{}])*
零次或多次。也就是说,一旦角色不匹配,改变有助于来回切换。如果第一个模式与角色不匹配,那么下一个模式将会出现并尝试匹配。如果两者都不匹配,则控件转移到下面的}
模式,因为我们将非捕获组定义为重复零次或多次。
}
匹配文字结束括号。