在Python中对同一字符串多次使用re.match()
我有一个正则表达式,用来找到 :ABC:`hello` 这种模式。下面是代码。
format =r".*\:(.*)\:\`(.*)\`"
patt = re.compile(format, re.I|re.U)
m = patt.match(l.rstrip())
if m:
...
当这一模式在一行中出现一次时,它运行得很好。但是在一个例子中,像这样 ":tagbox:`Verilog` :tagbox:`Multiply` :tagbox:`VHDL`",它只找到最后一个。
我该怎么才能找到这三个模式呢?
编辑
根据 Paul Z 的回答,我用下面的代码解决了这个问题。
format = r"\:([^:]*)\:\`([^`]*)\`"
patt = re.compile(format, re.I|re.U)
for m in patt.finditer(l.rstrip()):
tag, value = m.groups()
print tag, ":::", value
结果
tagbox ::: Verilog
tagbox ::: Multiply
tagbox ::: VHDL
3 个回答
0
re.findall 或者更好的选择 regex.findall 可以用一行代码帮你完成这个任务:
import regex as re #or just import re
s = ":tagbox:`Verilog` :tagbox:`Multiply` :tagbox:`VHDL`"
format = r"\:([^:]*)\:\`([^`]*)\`"
re.findall(format,s)
结果是:
[('tagbox', 'Verilog'), ('tagbox', 'Multiply'), ('tagbox', 'VHDL')]
2
一个好的起点是re
模块的文档。除了re.match
(这个方法是从字符串的开头开始查找),还有re.findall
(这个方法会找到所有不重叠的模式出现),以及编译后的RegexObject
的match
和search
方法,这两个方法都可以指定开始和结束的位置,以限制查找的字符串部分。还有split
方法,它会根据模式把字符串分割成一个子字符串的列表。根据你想要的输出格式,这些方法中的某一个可能会对你有帮助。
9
是的,dcrosta建议你去看看re
模块的文档,这个建议挺不错的,但我猜你其实想用的是finditer
这个函数。试试这个:
format = r"\:(.*)\:\`(.*)\`"
patt = re.compile(format, re.I|re.U)
for m in patt.finditer(l.rstrip()):
tag, value = m.groups()
....
你现在的解决方案总是找到最后一个匹配,因为最开始的.*
会尽量多地匹配字符,直到找到一个有效的匹配(也就是最后一个)。顺便说一下,这样做可能会让你的程序变得非常慢,因为.*
会先尝试匹配整个字符串,然后再一个字符一个字符地回退,直到剩下的表达式告诉它“这匹配得太多了,回去吧”。使用finditer
应该会更高效。