
本文介绍如何精准匹配常见的 html 块级标签(如 `
`、`
- ` 等)及其闭合结构,确保标签对完整保留在结果中,避免破坏语义;强调 `re.finditer` + 捕获组 + 反向引用的正确用法,并指出正则处理 html 的局限性。
在文本处理中,若需按特定 HTML 标签“切分”字符串,但又要求保留完整的起始-结束标签对(如 <li>…</li>)且不丢失嵌套结构或标签本身,直接使用 re.split() 会将分隔符(即标签)剥离,导致结果中缺失关键标记——这正是原始需求的根本痛点。
此时,正确思路应是 “匹配”而非“分割”:使用 re.finditer() 配合支持反向引用的正则表达式,精准捕获成对出现的开放/闭合标签及其内部内容。
推荐正则模式如下:
import re pattern = r"<(p|li|ul|ol|dl|h1|h2|h3|h4|h5|h6)>[^<]*</\1>" subject = '<p> Some text some text some text. </p> <p> Another text another text </p>. <li> some list </li>. <ul> another list </ul>' matches = [match.group(0) for match in re.finditer(pattern, subject, re.DOTALL)] print(matches) # 输出: # ['<p> Some text some text some text. </p>', # '<p> Another text another text </p>', # '<li> some list </li>', # '<ul> another list </ul>']
✅ 关键解析:
立即学习“前端免费学习笔记(深入)”;
- (p|li|ul|ol|dl|h1|...h6) —— 捕获标签名到第一组;
- </\1> —— 精确匹配对应闭合标签(如 <li> → </li>),杜绝 <li>...</ul> 类错配;
- [^<]* —— 匹配标签内不含 < 的纯文本(适用于无嵌套、无属性的简化场景);
- re.DOTALL —— 使 . 可匹配换行符,提升多行内容兼容性。
⚠️ 注意事项:
- 此方案不支持标签属性(如 <p class="intro">)或嵌套结构(如 <ul><li>text</li><li><strong>nested</strong></li></ul>),因 [^<]* 会提前终止匹配;
- 若需处理真实 HTML(含属性、注释、自闭合标签、JS/CSS 内容等),务必改用专业 DOM 解析器,例如:
from bs4 import BeautifulSoup soup = BeautifulSoup(subject, 'html.parser') for tag in soup.find_all(['p', 'li', 'ul', 'ol', 'dl', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6']): print(str(tag)) # 完整保留标签、属性、子节点及格式
? 总结:正则适用于可控、扁平、无属性的 HTML 片段提取;而真实 Web 内容解析,请始终优先选用 BeautifulSoup、lxml 或 html.parser 等成熟 DOM 工具——它们健壮、可维护,且能正确处理 HTML 规范中的所有边界情况。











