我想在乳胶文件中进行搜索和替换,如下所示:
:%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}"
答案 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
中的所有内容。