python,多个匹配组

时间:2013-07-20 16:31:10

标签: python regex python-3.x

我有一个字符串:

s = '&nbsp;<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'&nbsp;.*(>\d*<\\/td>.*)*<\\/tr>')
m = p.match(s)

我确信有一个html / xml解析模块可以解决我的问题,我也可以分割字符串并处理该输出,但我真的想用re模块来做。谢谢!

4 个答案:

答案 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)

其他答案给出了可行的正则表达式,但值得理解为什么你的正则表达式没有。

你所有的比赛都是贪婪的和可选的(*)。所以你的正则表达式说:

  • &nbsp;
  • 任何内容的0个或更多字符
  • 0次或更多次捕获组
  • </tr>

“0或更多任何字符”会占用字符串的其余部分,不会为捕获组留下任何内容,因为它是可选的,因此成功匹配。

如果您想重新设计正则表达式,您可能希望使用.*?而不是.*来匹配字符串开头的垃圾。 ?使得匹配不正确,因此它将匹配尽可能少的字符而不是尽可能多的字符。

答案 3 :(得分:1)

你的表达式没有返回任何匹配,因为我写错了。而不是打印:

p = re.compile(r'&nbsp;.*(>\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']