解析乳胶宏槽 sed

Parse latex macro trough sed

提问人:fauve 提问时间:9/14/2023 最后编辑:fauve 更新时间:9/15/2023 访问量:27

问:

总体概览

目标是匹配所有匹配项的内容,以将其转换为 .\foo<p>content of \foo</p>

细节

目标是将一些 LaTeX 宏的内容从左括号匹配到右括号。

但是,可能会出现两个问题。对于贪婪,如果宏以同一行结尾之后有一个右括号,如 ,则将匹配 。lorem ipsum \foo{dolor} sit amet et consectetur \bar{}s/\\foo{.*}/\1/dolor} sit amet et consectetur \bar{}

但是,在不贪婪的情况下,我可以匹配里面第二个宏的右括号。例如,with 将匹配 .\\foolorem ipsum \foo{dolor \bar{sit amet} et consecteur} quia adipts/\\foo{.\{-}}/\1/dolor \bar{sit amet

在小而贪婪的情况下,我都无法匹配宏内容,而只能匹配宏内容。

问题

那么,如何将左括号的宏内容与相应的右括号进行匹配呢?

另一个问题:我使用 sed 是不是错了,那么我应该使用更专用的 LaTeX 解析工具吗?

正则表达式 解析 latex 文件转换 非贪婪

评论


答:

0赞 helper 9/15/2023 #1

perl 通过一个包 Text::Balanced 提供了此功能

我使用perl修复了以下形式的Latex输出:

从:

\noindent {\tt// substitute into diffEQ }
\begin{dmath} \label{eq:3}
b \frac{d^{}\left(\text{a*(1-exp(-c*t))}\right)}{\mathrm{dt^{}}}+k a \left(1-\mathrm{e}^{-c t}\right)=F
\end{dmath}

自:

\noindent {\tt// substitute into diffEQ }
\begin{dmath} \label{eq:3}
b \frac{d^{}\left({a (1-\mathrm{e}^{-c t})}\right)}{\mathrm{dt^{}}}+k a \left(1-\mathrm{e}^{-c t}\right)=F
\end{dmath}

其结果为:

Rendered Latex

使用以下代码:

perl -MText::Balanced -MData::Dumper -nlE '
    @brac = Text::Balanced::extract_bracketed($_, "{}", "^.*\\\\left\\(\\\\text");
    while ( defined(@brac[0]) ) {
#if(defined(@brac[0])) { print Data::Dumper::Dumper(\@brac)."\n" };
#print @brac[2], @brac[0], @brac[1];
    if(defined(@brac[0])) { modify_exp() };
    $_ = @brac[2] . @brac[0] . @brac[1];
    @brac = Text::Balanced::extract_bracketed($_, "{}", "^.*\\\\left\\(\\\\text");
    };
    print $_;

sub modify_exp {
    $brac[0] =~ s/\*/ /g;
    my @sub_brac = Text::Balanced::extract_bracketed($brac[0], "()", "^.*exp");
#print Data::Dumper::Dumper(\@sub_brac)."\n" ;
    $sub_brac[0] =~ s/\((.*)\)$/\\mathrm{e}^{$1}/g;
    $sub_brac[2] =~ s/exp//;
    $brac[0] = @sub_brac[2] . @sub_brac[0] . @sub_brac[1];
#print $brac[0];
#   $brac[0] =~ s/^{//;
#   $brac[0] =~ s/}$//;
    $brac[2] =~ s/\\text$//;
}
' "$1" 

注释行用于调试代码。以下链接介绍了该包:

https://metacpan.org/pod/Text::Balanced

0赞 helper 9/15/2023 #2

有时可以通过使用一个技巧来使用 sed,即使用以第一个括号开头的正则表达式,然后包含尽可能多的非右括号的字符,例如“{[^}]*”。不过,找到匹配的支架可能是一个问题。如果,在这个问题的情况下:

删除所有出现的命令,保留命令参数

如果匹配的括号后面跟着一个空格,或者可能是其他一些字符,则 sed 可以工作。