不够用;re.sub()仅适用于结构简单、无脚本和嵌套的纯静态HTML片段,面对script/style/pre、自闭合标签、属性含尖括号等场景极易误判,应优先使用html.parser、lxml或Prettier等专业解析器。

用 re.sub() 格式化 HTML 真的够用吗?
够用,但只适用于结构简单、标签嵌套不超过 1 层、且不包含 JavaScript 或 CSS 片段的纯静态 HTML 片段。一旦遇到 <script>console.log("<div>")</script> 或 这类内容,正则会直接误判闭合关系。<code><div></div></code>
常见错误现象:re.sub(r'', r'', html) 会让 崩溃; 类自闭合标签被错误补成 ;属性值里的引号和尖括号混在一起时,匹配提前终止。
- 只处理已知安全片段,比如服务端返回的、经过去脚本清洗的 HTML 字符串
- 避免匹配属性值内部(用
[^>]*替代.*?,但仍有边界风险) - 优先用
html.parser或lxml解析后再缩进输出,比正则健壮得多
BeautifulSoup 的 prettify() 为什么有时缩进错乱?
因为默认使用 hellohtml.parser,它对“哪些标签是 inline”、“哪些能省略闭合”依赖内置规则,而这些规则和浏览器实际解析行为不完全一致。比如
被认为不能出现在 内,prettify() 可能把它提到外面,导致缩进层级跳变。使用场景:适合快速查看结构、调试模板输出、或对格式精度要求不高的日志打印。
- 显式指定解析器:
BeautifulSoup(html, 'lxml') 比 'html.parser' 更贴近浏览器行为
- 控制缩进宽度:
soup.prettify(indent_width=2)
- 禁用自动修正:
BeautifulSoup(html, 'html.parser', parse_only=SoupStrainer()) 可减少重排,但无法完全关闭
手动实现最小可行缩进器要注意什么?
核心不是“怎么加空格”,而是“怎么判断当前标签该缩进几层”。关键在状态机:遇到 就进一层,遇到 或自闭合标签(如
、![]()
)就不进层。但必须跳过注释、CDATA 和 <script></script>/ 内容。
htmlppt.skill
把任意文章或文档内容转换成精美的全屏翻页 HTML 演示文件(幻灯片风格)。当用户发来一篇文章、文档链接、Markdown 内容、或粘贴的文本,并且希望生成演示用的 HTML 时触发。支持任意内容来源:iWiki 链接、KM 链接、本地文件路径、直接粘贴的文本。生成的 HTML 文件保存到本地工作区,并通过企微直接发送给用户。触发词示例:帮我把这篇文章做成PPT、转成演示文档、生成HTML幻灯片、做个演示、转成可以演示的格式、article to deck、make a slide。
下载
容易踩的坑:
- 没识别
,把注释里的 当成标签开头
- 把
]]> 当成普通标签处理
- 忽略大小写:
和 应视为同一类标签- 属性里含
>(如 onclick="alert('>')")导致提前结束标签匹配
一个简短示例(仅示意逻辑,非完整实现):
stack = []
for match in re.finditer(r']*>|<!--.*?-->|', html, re.DOTALL | re.IGNORECASE):
if match.group(1) == '/': # 闭合标签
if stack: stack.pop()
elif match.group(2) and not is_void_tag(match.group(2)): # 开放标签且非自闭合
stack.append(match.group(2))
# …后续按 len(stack) 缩进
什么时候该放弃脚本,改用现成工具?
当你开始写第二版正则、或加了三层条件判断来绕过某个 里的 HTML 字符串时,就该停了。真实项目中的 HTML 很少“干净”,而 js-beautify(命令行或 Python 封装)、tidy、甚至 VS Code 的内置格式化(通过 prettier + prettier-plugin-html),都经过大量边缘 case 淬炼。
性能差异其实不大,但兼容性差太多:比如 在表格里的合法嵌套位置、/ 的配对规则、HTML5 新增的 行为——这些全靠正则硬编码,维护成本远高于引入一个稳定依赖。
真正难的不是写正则,是定义“格式化”的边界:要不要合并空白?是否重排属性顺序?是否展开自闭合标签?这些决策一旦写死,后面就很难改。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










