我有一个perl脚本,我使用它与bash脚本相结合,用一些Latex代码片段替换文件中的字符和一般嵌套分数。Perl脚本中控制分数替换的部分由以下函数给出:
sub process_latex {
my ($latex) = @_;
1 while $latex =~ s{
\\frac
\{
((?:[^{}]|(?R))*) # numerator (match balanced braces)
\}
\{
((?:[^{}]|(?R))*) # denominator (match balanced braces)
\}
}{
my ($numerator, $denominator) = ($1, $2);
$numerator = process_latex($numerator);
$denominator = process_latex($denominator);
"($numerator)/($denominator)";
}gex;
return $latex;
}
这个脚本可以成功地处理嵌套的分数表达式,这些表达式在任何深度的任何参数中都没有任何其他Latex命令。举个例子。使用这个脚本,我可以替换表达式
\frac{\frac{x11}{x12} x2}{\frac{y1}{y2 \frac{y31}{y32}} y4}
\frac{\frac{a1}{a2} \frac{b1}{b2}}{\frac{c1}{c2} \frac{d1}{d2}}
与
((x11)/(x12) x2)/((y1)/(y2 (y31)/(y32)) y4)
((a1)/(a2) (b1)/(b2))/((c1)/(c2) (d1)/(d2))
但它不适用于以下表达式
\frac{ \frac{1\frac{2}{3}}{4} a{} }{ b{} }
\frac{\epsilon+\gamma}{2^{-4\epsilon}}
\frac{\frac{1}{2} \textbf{a}}{b \textit{c}}
为此我应该
((1(2)/(3))/(4) a{} )/( b{} )
(\epsilon+\gamma)/(2^{-4\epsilon})
((1)/(2) \textbf{a})/(b \textit{c})
但结果却变成了
\frac{ (1(2)/(3))/(4) a{} }{ b{} }
\frac{\epsilon+\gamma}{2^{-4\epsilon}}
\frac{(1)/(2) \textbf{a}}{b \textit{c}}
我可以使用一些帮助来修改perl函数,以便正确替换Latex分数表达式,这些表达式可能在其参数中包含嵌套或链接的大括号对,例如\frac{a{}{}}{b}
或\frac{a}{b{{}}}
,其中a
和b
是一些通用的Latex命令。
1条答案
按热度按时间m528fe3b1#
问题是
(?R)
递归整个模式,它需要\frac
文本来开始匹配。一旦你替换了字符串中的一些\frac
,你可能再也找不到匹配了。因此,一个潜在的解决方案是只递归花括号之间的子字符串:
参见this online demo。
这里,
((?:[^{}]|(?R))*)
部分被([^{}]*(?:(?1)[^{}]*)*)
和([^{}]*(?:(?3)[^{}]*)*)
替换,以仅递归必要的模式部分,并且相应地调整替换(($1, $2)
=>($2, $4)
)。