隔离可以包含嵌套大括号的大括号内容

隔离可以包含嵌套大括号的大括号内容

在 TeX 文件中,我有以下命令\q{aaa}{blablabla},并且我想隔离参数blablabla。我已经用 sed 弄清楚了:

sed 's/\q{([^}\{])}{([^}\{])}/\2/g'

而且效果很好。

问题是当有嵌套的模式中的大括号 我想保留内部大括号。换句话说,如果

\q{aaa}{blablabla \label{BBB}}

期望的输出是

blablabla \label{BBB}

例如,我们可以想象我想保留的连续几个 LaTeX 命令

\q{aaa}{blablabla \label{BBB} blablabla \includegraphics{ccc.eps} blablabla \cite{somebody_year} blablabla 
\begin{itemize}
\item AAA
\item BBB
\end{itemize}
blablabla to conclude}

这种极端 MWE 的期望输出为

blablabla \label{BBB} blablabla \includegraphics{ccc.eps} blablabla \cite{somebody_year} blablabla 
\begin{itemize}
\item AAA
\item BBB
\end{itemize}
blablabla to conclude

这样的例子是一个非常(也许太)复杂的例子,因为我搜索的最终目标是优化手稿的修订(在审阅过程中)。

不确定是否可以在一行中完成sed...

答案1

普通的正则表达式无法做到这一点;需要平衡括号的语言不是常规语言正式意义上的。因此,您无法使用 正确执行此操作sed。幸运的是,像 Perl 这样的东西提供的正则表达式实际上不仅限于常规语言。

例如,这种令人厌恶的行为(改编自对SO的回答匹配平衡括号的正则表达式)似乎符合你想要的:

perl -0 -lne 'print "$2\n\n" while m/ \\q\{aaa\} ( \{ ( (?: [^}{]+ | (?1))*+ ) \} )/gx '

输入\q{aaa}{blablabla \label{BBB}} \foo{bar}{not this} \q{aaa}{bleh}给出输出

blablabla \label{BBB}

bleh

即匹配的部分之间打印有两个换行符。如上所述-0,它也应该适用于多行标签。您还可以更改print $2print $&以获得完整\q{aaa}{...}标签。

这基本上所做的是,开头\\q\{aaa\}匹配标签的常量部分,内部部分(?: [^}{]+ | (?1))*+匹配任意数量的东西,这些东西要么是不带大括号的字符串,要么是可以通过在第一个捕获组处递归来匹配的东西(设置括号),即里面有东西的匹配的大括号对。

.../ \\q\{aaa\} ( \{ ( (?: [^}{]+ | (?1))*+ ) \} )/ '
                ^1   ^2               |     ^2   ^1
                |                     |          |
                +---------------------+----------+ 
                        recurse to group 1

第二个捕获组用于捕获输出的部分。

相关内容