HTML 转 Markdown 编号列表应统一用 1. 开头,忽略 start 和 value 属性;嵌套列表用 4 空格缩进且子项仍用 1.;reversed 需预逆序处理;推荐用 HTML 解析器而非正则转换。

HTML <ol></ol> 转 Markdown 编号列表的核心规则
Markdown 的编号列表不依赖序号值,只看行首数字 + 点 + 空格的格式是否合法。浏览器渲染 <ol></ol> 时会自动计算序号(比如从 start="3" 开始),但 Markdown 解析器(如 CommonMark)完全忽略数字大小,一律按 1, 2, 3… 顺序渲染。所以转换时不必保留原始 start 值或 <li value="5">,直接统一用 1. 开头最安全。
常见错误现象:
- 手动写 3. 第三项 → 渲染仍为 “1. 第三项”
- 保留 <ol start="10"></ol> 中的 10 → 生成 10. xxx,但实际显示还是 1.
- 混用 1. 和 2. 在同一列表 → 可能被解析为两个独立列表
- 始终用
1.作为每一项的前缀(哪怕原 HTML 是倒序或跳号) - 确保每项后有且仅有一个空格:
1. 内容✅,1.内容❌ - 连续的
1.不影响渲染连贯性,解析器会自动重编号
嵌套 <ol></ol> 怎么转成 Markdown 多级编号
Markdown 原生不支持真正的多级编号语义(即二级列表也想显示为 1.1、1.2),所有主流解析器都把嵌套列表视为「缩进+无序或有序」的视觉结构,而非编号继承。所以:
使用场景:<ol>
<li>a</li>
<ol><li>b</li></ol>
</ol> → 应转为:
1. a 1. b
- 二级及以下必须用 4 空格或 1 Tab 缩进(推荐 4 空格,兼容性更好)
- 子列表依然用
1.,不要写1.1.或a.—— 这些不是标准 Markdown - 如果原 HTML 有
<ol type="a"></ol>,Markdown 无对应语法,只能降级为无序列表-或继续用1. - 注意缩进层级:每层嵌套多缩进 4 空格,不能混用 Tab 和空格(某些解析器会失败)
遇到 <li value="..."> 或 reversed 怎么办
value 属性和 reversed 是 HTML 特有控制,Markdown 完全没有等价机制。强行映射会导致不可预测结果(例如 Pandoc 会忽略 value,Typora 可能报错)。
将任意网站转换为文件系统,自动抓取网站并将页面挂载为 Markdown 文件,可使用 grep、diff、cat 等标准 Unix 命令进行搜索、比较、读取和浏览。
立即学习“前端免费学习笔记(深入)”;
性能 / 兼容性影响:
- 任何试图在 Markdown 里模拟非线性编号(如 5.、3.、7.)的做法,都会让输出脱离规范,多数静态站点生成器(Hugo/Jekyll)或编辑器无法正确处理
- reversed 列表(倒序渲染)在 Markdown 中只能靠人工调换 <li> 顺序再转,否则失去语义
- 直接丢弃
value和reversed属性,不写入 Markdown - 若业务强依赖倒序展示,先用脚本把
<li>节点逆序排列,再统一转1. - 避免在转换工具中添加“智能重编号”逻辑 —— 增加复杂度且无实际收益
用正则或脚本批量转换时的关键陷阱
正则替换看似简单,但容易漏掉边界情况。例如只匹配 <ol>...</ol> 而忽略嵌套,或把代码块里的 <ol></ol> 也误替换。
容易踩的坑:
- <ol></ol> 和 不在同一行时,单行正则(如 /<ol>(.*?)/s</ol>)可能跨度过大,捕获到不该包含的内容
- <li> 中含换行或内联 HTML(如 <strong></strong>)时,简单替换 <li> → 1. 会破坏结构
- 忘记处理自闭合标签或注释(如 <!-- comment -->)导致匹配错位
- 优先用 HTML 解析器(如 Python 的
BeautifulSoup、Node 的cheerio)做结构化提取,而非正则 - 对每个
<li>节点,用.get_text()提取纯文本,再拼接"1. " + text.strip() - 嵌套时递归处理子
<ol></ol>,并按深度控制缩进空格数(深度 × 4)
真正麻烦的从来不是“怎么编号”,而是 HTML 中那些没闭合的标签、混在列表里的 <div>、或者富文本编辑器导出的带 style 的 <code><li> —— 这些得先清洗,再谈转换。


















