re.match和re.search默认不匹配标签内容是因为.等贪婪量词会匹配到最末尾闭合标签;应改用.?等非贪婪模式,并配合1*防属性干扰,但HTML结构复杂时仍需改用BeautifulSoup。> ↩

为什么 re.match 和 re.search 默认不匹配到标签内容?
因为正则默认是贪婪模式,.* 会尽可能吞掉所有字符,直到最后一个闭合标签为止。比如用 re.search(r'<div>(.*)</div>', html) 处理 '<div>A</div>
<div>B</div>',捕获组得到的是 'A<div>B',根本不是你想要的“第一个 div 的内容”。
<h3>怎么写非贪婪匹配才真正提取单个标签内容?</h3>
<p>在量词后面加 <code>?:把 .* 换成 .*?,把 + 换成 +?。关键是要让正则“见到第一个闭合就停”。
- 提取最内层
<p>内容:re.search(r'<p>(.*?)</p>', html) - 提取带属性的
<span class="name">:re.search(r'<span>]*>(.*?)</span>', html)([^>]*防止误吞属性里的>) - 注意:如果标签跨行,得加
re.DOTALL标志,否则.不匹配换行符
哪些常见场景下 re 提取 HTML 会翻车?
非贪婪只是让匹配“短一点”,但不能解决 HTML 结构复杂性问题。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
立即学习“Python免费学习笔记(深入)”;
- 嵌套标签:
'<div><div>content</div></div>'中r'<div>(.*?)</div>'只能拿到'<div>content' —— 因为它匹配的是第一个 <code></div>,不是对应闭合 - 自闭合标签或注释干扰:
<img src="a>b">里属性值含>,[^>]*就失效了 - 大小写混用、空格不规则、CDATA 段等,正则很快失控
- 等价提取:
BeautifulSoup(html, 'html.parser').find('div').get_text()更稳 - 它自动处理编码、转义、嵌套、命名空间,而正则要手动补一堆边界条件
- 性能差异在小文本上几乎可忽略;可读性和维护成本差距巨大
什么时候该放弃 re 改用 BeautifulSoup?
只要 HTML 来源不可控(比如爬网页)、标签可能嵌套、需要可靠定位或后续操作 DOM,就别硬刚正则。
非贪婪匹配本身没问题,但把它当成 HTML 解析方案,就像用螺丝刀撬保险柜——力道够了,结构不对。


















