You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何用Regex匹配含<br>的<span>元素时出现异常匹配?

为什么你的正则会匹配跨<span>的内容?

这其实是正则非贪婪匹配的一个典型陷阱,我来给你一步步拆解原因:

先看你的原始场景

你的目标字符串是:

xx= '<div> <span>123</span> <span>456 <br> 789</span> </div>'

第一个正则能正常工作的原因

你用<span>.*?</span>时,.*?是非贪婪匹配,它会尽可能少地匹配字符,直到遇到第一个</span>就停止。因为每个<span>内部没有嵌套的<span>或</span>标签,所以它能精准拆分出两个独立的<span>元素。

第二个正则出问题的核心

当你换成<span>.*?<br>.*?</span>时,问题出在.*?的匹配规则上:
正则里的.默认会匹配除换行外的任意字符——包括HTML标签本身(比如</span>、<span>这些字符串都会被当成普通字符匹配)。

具体匹配过程是这样的:

  1. 正则从第一个<span>开始匹配,第一个<span>内部没有<br>,所以.*?会一直往后“搜索”<br>;
  2. 它会跳过第一个</span>、第二个<span>的起始标签,直到找到目标<br>;
  3. 接着后面的.*?匹配到最近的</span>,最终就把从第一个<span>到最后一个</span>的整个片段都当成了一个匹配结果。

怎么修复这个正则?

你需要限制.*?不能跨<span>标签匹配,这里可以用负向预查来实现,修改后的正则如下:

re.findall(r'<span>(?:(?!</?span>).)*?<br>(?:(?!</?span>).)*?</span>', xx)

这里的(?:(?!</?span>).)是关键:它表示“当前位置后面不是<span>或</span>的任意单个字符”,这样就把匹配范围牢牢限制在单个<span>内部了,不会跨标签匹配。

额外小提醒

虽然你知道正则解析HTML不是规范做法,但还是建议试试BeautifulSoup——它对不规范HTML的容错性比lxml更强,用它来筛选包含<br>的<span>会比正则靠谱得多,代码也更易维护。

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:58:31