3

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

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

那应该将“”之类的文本转换abc \todo{def} ghi为“ abc def ghi”。碰巧当\todo{...}命令在另一个命令中时,vim 会尝试将第二个(右)括号与外部命令的括号匹配。例如,当它应该是“ ”时,“ abc \textbf{def \todo{ghi} jkl}”变成了“ ”。abc \textbf{def ghi} jklabc \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}"
4

3 回答 3

1

非递归

告诉它匹配除 {} 之外的任何内容:

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

递归的

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

但是,您可以使用 perl 之类的外部语言来执行此操作:

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

有关递归正则表达式的更多信息,请查看此 SO 帖子。我还发现We's Puzzling Blog有助于找出这些正则表达式。

于 2012-11-29T20:47:21.860 回答
0

你不希望你的正则表达式是贪婪的。查看答案如何在 vim 中使我的匹配不贪心?

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

:%s/\v\\todo\{(.{-})\}/\1/gc
于 2012-11-29T20:35:47.867 回答
0

可以使用正则表达式匹配嵌套模式吗?不。

我们可以支持一级嵌套,如下所示:

我们想在\todo{}. 所以我们必须尽可能多地[^{}]匹配{[^{}]*}

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

我们添加了一个额外\(\)的东西来将整个东西存储在\1.

于 2012-11-29T21:42:36.347 回答