求助:为何re.findall仅返回最后一组匹配结果?
问题分析与解决方案
你的正则表达式只匹配到最后一组结果,核心问题出在**贪婪模式的.***上,具体原因和修复方法如下:
为什么只匹配到最后一组?
你的正则是:
re.findall(r'<td.*>(\d\d:\d\d)</td><td.*>(.*?)</td>', HTML)
其中<td.*>里的.*是贪婪匹配,它会尽可能多地匹配字符,直到后面的模式((\d\d:\d\d)</td>...)能找到匹配项。在你的HTML字符串中,正则引擎会跳过第一个时间戳10:10,直接匹配到最后一个时间戳10:30所在的<td>标签——因为这样能让.*匹配最多的内容,最终只捕获到最后一组结果。
修复正则表达式
把贪婪的.*改成非贪婪的.*?,让它匹配到第一个>就停止,这样就能正确识别每一组的<td>标签;同时加上\s*匹配标签间的空白字符,让正则更鲁棒:
re.findall(r'<td.*?>(\d\d:\d\d)</td>\s*<td.*?>(.*?)</td>', HTML)
测试后你会得到预期的两组结果:
[('10:10', 'This is a description.'), ('10:30', 'This is another description.')]
额外建议:避免用正则处理HTML
正则并不适合解析HTML这类结构化文档——一旦HTML结构有微小变化(比如新增属性、换行、空格),正则就可能失效。更可靠的方式是用专门的HTML解析库,比如BeautifulSoup:
from bs4 import BeautifulSoup soup = BeautifulSoup(HTML, 'html.parser') results = [] for tr in soup.find_all('tr'): tds = tr.find_all('td') if len(tds) == 2: time = tds[0].get_text(strip=True) desc = tds[1].get_text(strip=True) results.append((time, desc))
这种方法能轻松应对各种HTML结构变化,维护性更强。
内容的提问来源于stack exchange,提问作者scuzzi
相关产品推荐
相关产品推荐

