
本文介绍如何通过正则表达式精准匹配成对的 html 标签(如 `
- ...
在处理 HTML 片段时,若目标是“按特定成对标记切分字符串并保留标签本身”,直接使用 re.split() 会将分隔符(即标签)从结果中移除,导致结构丢失。例如,用 re.split(r'<li>|<ul>', s) 会把 <li> 和 <ul> 当作分界点丢弃,无法满足“保留完整标签块”的需求。
正确做法是改用 re.finditer() 或 re.findall() 进行匹配(match)而非分割(split),并构造能捕获开闭标签配对 + 中间内容的正则模式。推荐使用如下表达式:
import re pattern = r"<(p|li|ul|ol|dl|h1|h2|h3|h4|h5|h6)>[^<]*</\1>" test_string = '<p> Some text some text. </p> <p> Another text </p>. <li> some list </li>. <ul> another list </ul>' matches = [match.group(0) for match in re.finditer(pattern, test_string, re.DOTALL)] print(matches) # 输出: # ['<p> Some text some text. </p>', '<p> Another text </p>', '<li> some list </li>', '<ul> another list </ul>']
该正则核心解析如下:
- <(:匹配 < 后紧跟一个捕获组;
- (p|li|ul|ol|dl|h1|h2|h3|h4|h5|h6):限定支持的标签名(可按需增删);
- >[^<]*</\1>:匹配 >,随后是非 < 字符任意次(即标签内纯文本),再匹配闭合标签 </ + 与前面捕获组相同的内容(\1 实现标签名回溯),最后是 >。
⚠️ 注意事项:
立即学习“前端免费学习笔记(深入)”;
- 此方案仅适用于简单、格式良好、无嵌套、无属性、无自闭合标签(如 <img/>)的 HTML 片段;
- [^<]* 不支持标签内含 <(如内联脚本、注释或嵌套标签),实际 HTML 中极易失效;
- 若输入含属性(如 <div class="list">...</div>)或换行/空白复杂,该正则将无法匹配;
- 生产环境强烈建议使用专业 HTML 解析器(如 BeautifulSoup 或 lxml),它们能稳健处理真实 HTML 的所有边界情况。
✅ 推荐替代方案(BeautifulSoup 示例):
from bs4 import BeautifulSoup soup = BeautifulSoup(test_string, 'html.parser') target_tags = soup.find_all(['p', 'li', 'ul', 'ol', 'dl', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6']) result = [str(tag) for tag in target_tags]
综上:正则匹配成对标签是快速原型开发的有效手段,但应明确其局限性;涉及真实 HTML 处理时,请优先选用 DOM 解析器,兼顾健壮性与可维护性。











