我有一个像这样的python正则表达式:
re.compile(r'(\[chartsjs\].*\[/chartsjs\])', re.DOTALL)
我正在尝试对这样的模式进行re.findall
:
[charts]
name: mychart
type: line
labels: fish, cat, dog
data: 4, 5, 6
data2:5, 7, 9
[/charts]
this is some text
[charts]
name: second
type: line
labels: 100, 500, 1000
data: 50, 100, 10000
data2: 100, 100, 100
[/charts]
但似乎它匹配第一个[charts]
到最后一个[charts]
并抓住中间的所有内容,因为当我将它打印到控制台时我看到了这个:
[u'[chartsjs]\r\nname: mychart\r\ntype: line\r\nlabels: fish, cat, dog\r\ndata: 4, 5, 6\r\ndata2:5, 7, 9\r\n[/chartsjs]\r\n\r\nthis is some text now fool\r\n\r\n[chartsjs]\r\nname: second\r\ntype: line\r\nlabels: 100, 500, 1000\r\ndata: 50, 100, 10000\r\ndata2: 100, 100, 100\r\n[/chartsjs]']
我希望正则表达式返回第一个匹配,消除任意测试,然后找到另一个任意数量的匹配。有没有办法做到这一点?
答案 0 :(得分:5)
你的正则表达式只有一个问题。
.*
会贪婪地匹配其路径中的所有内容。当遇到第一个结束[/charts]
时,它将进一步检查是否还有更多[/charts]
。如果找到,那么它将继续。
要让它在第一个[/charts]
停止,我们需要通过添加问号使其变得懒惰。 .*?
这将保持匹配所有内容并在第一个[/charts]
看看我测试过它:
import re
a="""
[charts]
name: mychart
type: line
labels: fish, cat, dog
data: 4, 5, 6
data2:5, 7, 9
[/charts]
this is some text
[charts]
name: second
type: line
labels: 100, 500, 1000
data: 50, 100, 10000
data2: 100, 100, 100
[/charts]
"""
for c in re.findall('(\[charts\].*?\[/charts\])',a, re.DOTALL):
print c
输出:
[charts]
name: mychart
type: line
labels: fish, cat, dog
data: 4, 5, 6
data2:5, 7, 9
[/charts]
[charts]
name: second
type: line
labels: 100, 500, 1000
data: 50, 100, 10000
data2: 100, 100, 100
[/charts]
答案 1 :(得分:1)
这里最重要的是你希望。*成为。*?。还有其他方法来优化正则表达式,正如其他人已经回答的那样,但我认为你的问题的根源是你想要匹配所有你看到的那些[/ charts]模式,哪个?会给你。