如何用正则匹配LaTeX文档中带嵌套花括号的\theoremnoname命令
匹配带嵌套大括号的LaTeX定理结构的正则方案
要处理LaTeX中\theoremnoname{Something 1}{Something 2}这种可能包含嵌套{}的结构,关键是要递归匹配嵌套的大括号——普通正则(不支持递归)无法处理这类场景,得用支持递归/平衡组的正则引擎(比如Python的regex库、.NET正则引擎、PCRE等)。
具体实现方案
1. 核心正则表达式(支持递归)
针对需求,可使用如下正则直接提取两组内容:
\\theoremnoname\{((?:[^{}]|(?R))*)\}\{((?:[^{}]|(?R))*)\}
- 关键解释:
\\theoremnoname:匹配目标命令,注意转义反斜杠\{((?:[^{}]|(?R))*)\}:匹配一对大括号内的内容,其中(?:[^{}]|(?R))*表示要么匹配非大括号字符,要么递归匹配整个大括号结构,完美处理任意层级的嵌套{}- 两个独立分组分别对应
Something 1和Something 2
2. Python示例(使用regex库)
Python标准库re不支持递归,需安装第三方库regex:
import regex latex_content = """ \\theoremnoname{$\\sqrt{2}$ is irrational.}{Blah {blah} blah...} \\theoremnoname{For $n$ a non-square integer, $\\sqrt{n}$ is irrational.}{Proof {with nested {braces} here} done.} """ pattern = r'\\theoremnoname\{((?:[^{}]|(?R))*)\}\{((?:[^{}]|(?R))*)\}' matches = regex.findall(pattern, latex_content) for idx, (thm_statement, thm_proof) in enumerate(matches, 1): print(f"定理{idx} 陈述:{thm_statement}") print(f"定理{idx} 内容:{thm_proof}\n")
运行后会正确提取包含多层嵌套大括号的两组内容。
3. 有限嵌套场景的替代方案(仅用标准re)
如果只能用Python标准库re,可以通过有限层级的嵌套规则近似处理,比如支持2层嵌套的正则:
\\theoremnoname\{([^{}]*(?:\{[^{}]*\}[^{}]*)*)\}\{([^{}]*(?:\{[^{}]*\}[^{}]*)*)\}
但这种方法无法处理更深层级的嵌套,仅适合简单场景。
原正则失效原因
你之前的正则\theorem\{([^{}]+)\}(\{([^{}]*\{[^{}]*\}[^{}]*)*)\})存在两个问题:
- 匹配的是
\theorem而非目标的\theoremnoname - 第二个分组的逻辑无法处理多层嵌套的大括号,导致无法匹配复杂内容
内容的提问来源于stack exchange,提问作者Robin
相关产品推荐
相关产品推荐

