我有一个字符串:
s = ' <span>Mil<\/span><\/th><td align=\"right\" headers=\"Y0 i7\">112<\/td><td align=\"right\" headers=\"Y1 i7\">113<\/td><td align=\"right\" headers=\"Y2 i7\">110<\/td><td align=\"right\" headers=\"Y3 i7\">107<\/td><td align=\"right\" headers=\"Y4 i7\">105<\/td><td align=\"right\" headers=\"Y5 i7\">95<\/td><td align=\"right\" headers=\"Y6 i7\">95<\/td><td align=\"right\" headers=\"Y7 i7\">87<\/td><td align=\"right\" headers=\"Y8 i7\">77<\/td><td align=\"right\" headers=\"Y9 i7\">74<\/td><td align=\"right\" headers=\"Y10 i7\">74<\/td><\/tr>'
我想从字符串中提取这些数字:
112 113 110 107 105 95 95 87 77 74 74
我不是正则表达式的专家,所以任何人都可以告诉我,为什么这不会返回任何匹配项:
p = re.compile(r' .*(>\d*<\\/td>.*)*<\\/tr>')
m = p.match(s)
我确信有一个html / xml解析模块可以解决我的问题,我也可以分割字符串并处理该输出,但我真的想用re模块来做。谢谢!
答案 0 :(得分:4)
>>> r = re.compile(r'headers="Y\d+ i\d+">(\d+)<\\/td>')
>>> r.findall(s)
['112', '113', '110', '107', '105', '95', '95', '87', '77', '74', '74']
>>>
答案 1 :(得分:4)
您想要的所有数字都在“&gt;”之间和“&lt;”。所以,你可以这样做:
re.findall(">(\d+)<", s)
输出:
['112', '113', '110', '107', '105', '95', '95', '87', '77', '74', '74']
基本上,它是说每个数字流都在“&gt;”之间和“&lt;”。然后,使用set
,您只能获得唯一的。
答案 2 :(得分:2)
其他答案给出了可行的正则表达式,但值得理解为什么你的正则表达式没有。
你所有的比赛都是贪婪的和可选的(*
)。所以你的正则表达式说:
</tr>
“0或更多任何字符”会占用字符串的其余部分,不会为捕获组留下任何内容,因为它是可选的,因此成功匹配。
如果您想重新设计正则表达式,您可能希望使用.*?
而不是.*
来匹配字符串开头的垃圾。 ?
使得匹配不正确,因此它将匹配尽可能少的字符而不是尽可能多的字符。
答案 3 :(得分:1)
你的表达式没有返回任何匹配,因为我写错了。而不是打印:
p = re.compile(r' .*(>\d*<\\/td>.*)*<\\/tr>')
m = p.match(s)
您可能应该打印出来:
>>> p = re.compile(r'headers="Y\d+ i\d+">(\d+)<\\/td>')
>>> p.findall(s)
['112', '113', '110', '107', '105', '95', '95', '87', '77', '74', '74']