如何在Vim中使用搜索和替换从latex文件中删除命令?

时间:2012-11-29 20:32:31

标签: regex vim

我想在乳胶文件中进行搜索和替换,如下所示:

:%s/\\todo{.*}/\1/gc

这应该改变像" abc \todo{def} ghi"进入" abc def ghi"。碰巧当\todo{...}命令在另一个命令中时,vim会尝试将第二个(结束)括号与外部命令的括号匹配。例如," abc \textbf{def \todo{ghi} jkl}"成为" abc \textbf{def ghi} jkl"什么时候应该是" abc \textbf{def ghi jkl}"。

有没有办法匹配相应的括号?

修改

很抱歉没有指出它。如果它可以完全匹配相应的括号,那将是很好的,因为内部可以有命令以及\todo{...}命令。

修改

"abc \todo{def \textbf{ghi} jkl}" -> "abc def \textbf{ghi} jkl"
"abc \textbf{def \todo{ghi} jkl}" -> "abc \textbf{def ghi jkl}"

3 个答案:

答案 0 :(得分:1)

非递归

告诉它匹配{} s以外的任何内容:

:%s/\\todo{\([^{}]\+\)}/\1/

<强>递归

Vim正则表达式语言不支持以您建议的方式匹配模式所需的conditional regexes

但是,您可以使用像perl这样的外部语言:

:perldo $_ =~ s/\\todo ({( (?: [^{}]*+ | (?1) )* )}) /\2/gx

有关递归正则表达式checkout this SO post的更多信息。我还发现We's Puzzling Blog有助于提出这些类型的正则表达式。

答案 1 :(得分:0)

你不希望你的正则表达式贪婪。请参阅回答How can I make my match non greedy in vim?

在你的情况下,这应该可以解决问题:

:%s/\v\\todo\{(.{-})\}/\1/gc

答案 2 :(得分:0)

Can regular expressions be used to match nested patterns?没有。

我们可以支持以下一级嵌套:

我们想在\todo{}内配对花括号。 因此,我们必须尽可能多地匹配[^{}]{[^{}]*}

:%:s/\\todo{\(\([^{}]\|{[^{}]*}\)*\)}/\1/

我们添加了额外的\(\)来存储\1中的所有内容。