如何用Perl正则匹配一级嵌套内的LaTeX命令并添加/移除花括号
Perl正则匹配一级嵌套LaTeX命令,添加/移除花括号
需求说明
需要用Perl正则实现:给**一级嵌套(即位于其他LaTeX命令的参数花括号内部)**的指定LaTeX命令(如\com1)添加外层花括号,或移除已有的外层花括号。LaTeX命令结构为:以\开头,后跟命令名,可选方括号参数,再跟任意数量的平衡花括号对(内部可嵌套其他LaTeX命令)。
现有方案局限
目前仅能匹配**零级(最外层)**的目标命令:
- 添加花括号的正则:
(?<=[^{])(\\(?:com1)(?:\[[^[]]*\])?(\{((?>[^{}]|(?2))*)\})*)
替换为{$1},可将零级的\com1[opts]{...}{...}转为{\com1[opts]{...}{...}}。
- 移除花括号的正则:
\{(\\(?:com1)(?:\[[^[]]*\])?(\{((?>[^{}]|(?2))*)\})*)\}
替换为$1,可将零级的{\com1[opts]{...}{...}}转回\com1[opts]{...}{...}。
但当目标命令处于其他LaTeX命令的参数内部时,无法处理括号平衡问题,无法匹配一级嵌套的命令。
期望效果
- 给一级嵌套的
\com1添加花括号:
原文本:
\rpl{text}{ some\com1[opts]{ some \qtyrange{100}{200}{\celsius} and }{something else \gls{abc} $1=1$ not \colortext{\red}{\underline{text}}} but this is already braced {\qtyrange{100}{200}{\celsius}}}
转换后:
\rpl{text}{ some {\com1[opts]{ some \qtyrange{100}{200}{\celsius} and }{something else \gls{abc} $1=1$ not \colortext{\red}{\underline{text}}}} but this is already braced {\qtyrange{100}{200}{\celsius}}}
- 从上述结果移除
\com1的外层花括号,得到:
\rpl{text}{ some \com1[opts]{ some \qtyrange{100}{200}{\celsius} and }{something else \gls{abc} $1=1$ not \colortext{\red}{\underline{text}}} but this is already braced \qtyrange{100}{200}{\celsius}}
解决方案
利用Perl支持递归正则和\G锚点的特性,精准锁定一级嵌套上下文并处理目标命令:
1. 给一级嵌套的\com1添加外层花括号
s/(?:\G(?!\A)|\\[a-zA-Z]+\{[^{}]*)\K(?<!\{)\\com1(?:\[[^\]]*\])?(?:\{(?:[^{}]|(?R))*\})+/{$&}/g;
- 逻辑说明:
(?:\G(?!\A)|\\[a-zA-Z]+\{[^{}]*):锁定一级嵌套的上下文——要么是上一次匹配结束的位置,要么是任意LaTeX命令的参数花括号起始后的内容。\K:忽略前面匹配的上下文内容,仅对后续目标命令做替换。(?<!\{):确保\com1未被花括号包裹。\\com1(?:\[[^\]]*\])?(?:\{(?:[^{}]|(?R))*\})+:匹配完整的\com1命令,包括可选方括号参数和所有平衡花括号参数。- 替换为
{$&}:给匹配到的命令添加外层花括号。
2. 移除一级嵌套中\com1的外层花括号
s/(?:\G(?!\A)|\\[a-zA-Z]+\{[^{}]*)\K\{(\\com1(?:\[[^\]]*\])?(?:\{(?:[^{}]|(?R))*\})+)\}/$1/g;
- 逻辑说明:
- 前半部分
(?:\G(?!\A)|\\[a-zA-Z]+\{[^{}]*)和\K作用同上,锁定一级嵌套上下文。 \{(\\com1(?:\[[^\]]*\])?(?:\{(?:[^{}]|(?R))*\})+)\}:匹配被外层花括号包裹的完整\com1命令。- 替换为
$1:移除外层花括号。
- 前半部分
注意事项
- 若需限定仅处理特定外层命令(如只处理
\rpl内部的\com1),可将正则中的\\[a-zA-Z]+改为\\rpl。 - 需使用Perl 5.10及以上版本,确保支持递归正则和
\G锚点特性。 - 正则不会误匹配数学环境(
$...$)内的内容,符合需求场景。
内容的提问来源于stack exchange,提问作者atapaka
相关产品推荐
相关产品推荐

