正则表达式不能真正理解Markdown列表语义层级,但可在逻辑已正确、仅需统一缩进的场景下机械对齐;需配合脚本推断层级并重写缩进。

正则表达式本身无法真正“理解” Markdown 列表的语义层级(比如识别嵌套关系、判断缩进是否合法),但它可以高效匹配和重写符合常见格式规律的缩进行为。关键在于:把问题限定在已有正确层级逻辑、仅需统一缩进风格的场景下,用正则完成机械性对齐。
明确目标格式与前提条件
正则适配的是“视觉缩进一致、逻辑层级已由符号(- / * / + / 1. )体现”的列表。例如:
- 一级列表项以
- item开头,顶格; - 二级列表项应缩进 2 或 4 个空格(或 1 个 Tab),且前面必须是上一级的列表项或空行;
- 不处理混用 Tab/空格、跨段落嵌套、代码块内列表等边界情况。
核心匹配模式(以 2 空格缩进为例)
用两步走:先提取带层级信息的原始行,再按深度重写缩进。
-
提取层级与内容:
^(\s*)([-*+]\s+|\d+\.\s+)(.+)$
捕获组1:现有缩进(用于推断当前层级);
捕获组2:列表标记(-或1.);
捕获组3:文本内容。 - 计算目标缩进:根据捕获组1长度 / 2(或 / 4)取整,得到当前“疑似层级”,再结合上下文修正(如前一行是二级,则下一行若带标记且无缩进,应视为同级而非降级)——这一步正则做不到,需配合简单脚本逻辑。
实用替代方案(推荐)
纯正则难以稳健处理层级推导,更可靠的做法是:
- 用正则提取所有列表行并标记原始缩进量,输出为带层级线索的中间结构;
- 用 Python/JS 等语言遍历行,根据列表符号类型(无序/有序)、缩进变化、空行分隔,动态维护当前层级栈;
- 最后用正则或字符串拼接,按目标缩进(如每级 2 空格)生成新行。
一个可运行的 Python 示例片段
(结合正则提取 + 逻辑判断)
import re
lines = md_text.split('\n')
result = []
stack = [0] # 当前层级栈,初始为0(非列表)
for line in lines:
m = re.match(r'^(\s*)([-*+]\s+|\d+\.\s+)(.+)$', line)
if m:
indent_len = len(m.group(1))
marker = m.group(2)
content = m.group(3)
# 推断层级:基于缩进变化趋势,非绝对值
current_level = max(1, len(stack) - 1)
if indent_len > 0 and stack[-1] == 0:
current_level = 1
elif indent_len > 0:
current_level = min(len(stack), (indent_len + 1) // 2)
# 调整栈:出栈至合适深度,再入栈
while len(stack) > current_level:
stack.pop()
if len(stack)











