Regex 在Vim中,替换/搜索符号中是否有“匹配括号/括号/etc”等效项?

Regex 在Vim中,替换/搜索符号中是否有“匹配括号/括号/etc”等效项?,regex,vim,Regex,Vim,例如,我想用除括号内的换行符以外的任何内容替换foo{…},括号内可能有空格,其他括号打开和关闭,等等,后面不跟bar 例如,foo{{}}中的foo{{},bar将匹配,但不会匹配foo{hello{}bar 我试过/foo{.*}\bar\\@!和/foo{.\{-}}\bar\@!但是第一个将匹配foo{}bar{},第二个将只匹配foo{{}部分 foo{.*}\([}]*bar\)\@! 匹配项: foo{{ }} foo{{ }}, bar 但不是: foo{hello{}}ba

例如,我想用除括号内的换行符以外的任何内容替换foo{…},括号内可能有空格,其他括号打开和关闭,等等,后面不跟bar

例如,foo{{}}中的foo{{},bar将匹配,但不会匹配foo{hello{}bar

我试过/foo{.*}\bar\\@!和/foo{.\{-}}\bar\@!但是第一个将匹配foo{}bar{},第二个将只匹配foo{{}部分

foo{.*}\([}]*bar\)\@!
匹配项:

foo{{ }}
foo{{ }}, bar
但不是:

foo{hello{}}bar
不可能正确匹配任意级别的嵌套 使用正则表达式的括号。但是,可以 构造一个正则表达式来匹配支持有限数量的嵌套I 我认为这个答案并没有试图这么做

这是

对于最多一层的内支撑:

/foo{[^{}]*\({[^{}]*}[^{}]*\)*}\(bar\)\@!
/foo{[^{}]*\({[^{}]*\({[^{}]*}[^{}]*\)*}[^{}]*\)*}\(bar\)\@!
/foo{[^{}]*\({[^{}]*\({[^{}]*\({[^{}]*}[^{}]*\)*}[^{}]*\)*}[^{}]*\)*}\(bar\)\@!
对于最多两个级别的内支撑:

/foo{[^{}]*\({[^{}]*}[^{}]*\)*}\(bar\)\@!
/foo{[^{}]*\({[^{}]*\({[^{}]*}[^{}]*\)*}[^{}]*\)*}\(bar\)\@!
/foo{[^{}]*\({[^{}]*\({[^{}]*\({[^{}]*}[^{}]*\)*}[^{}]*\)*}[^{}]*\)*}\(bar\)\@!
对于多达三个级别的内支撑:

/foo{[^{}]*\({[^{}]*}[^{}]*\)*}\(bar\)\@!
/foo{[^{}]*\({[^{}]*\({[^{}]*}[^{}]*\)*}[^{}]*\)*}\(bar\)\@!
/foo{[^{}]*\({[^{}]*\({[^{}]*\({[^{}]*}[^{}]*\)*}[^{}]*\)*}[^{}]*\)*}\(bar\)\@!

具体取决于您希望执行的替换,您可以使用宏来执行

例如:给定此文本

第1行-----数组[a][b[1]] 第2行-数组[c][d] 第3行---数组[e[0]][f]+数组[g[0]][h[0]] 用getA,B替换数组[A][B]

为此:

将光标定位在文本的开头 /排列 qq开始录制宏 执行一些操作以独立于内部内容更改数据,使用%转到匹配的括号,并删除括号周围的数据。例如,cwgetldi[vhpa,ldi[vhpan-但宏通常不可读。 n去看下一场比赛,q停止录音 @q反复使用@可以从第二次开始使用 这可能不是很方便,因为很容易出错,例如按I,a,你必须从头开始重做宏,但它可以工作

或者,您可以执行类似于eregex.vim插件的操作来扩展vim的正则表达式格式以支持这一点,这样您就不必每次都重新键入庞大的正则表达式

概念证明:

不处理不同的魔法等级 不处理替换“sab”的“\/”或不同字符 不处理字符串中的括号 用法:`:M/pattern,使用\zm匹配块/替换/标志` 命令-range-nargs=*M:调用替换匹配, :M/灵感来源于eregex.vim 函数替换Matching命令,第1行,第2行 让EscapeRegex={pattern->escapepattern,[]\'} 让openbracket='[{' 让closebracket=']} 让nonbracketR='[^'.EscapeRegexopenbracket.closebracket']' 设nonbracketsR=nonbracketR.'*' 让LiftLevel={pattern-> \无括号 \.'\%' \“[”.EscapeRegexopenbracket.” \.模式 \“[”.EscapeRegexclosebracket.]” \.无括号SR \.'\*' \} 让匹配r=liftlevelliftlevelliftlevelvelnonbracketsr if v:false可选测试套件 回显返回0: 回显匹配'abc','^'。匹配r.'$' 回显匹配'abcabde','^'。匹配r.'$' 回显匹配'abcabdef','^'。匹配r.'$' 回显匹配'abca[x]bdef','^'.matchingR'.$' 回显匹配'abca]b','^'。匹配r.'$' 如果只有一种类型的支架,或者 代码格式良好 回波返回-1: 回显匹配'abcab','^'。匹配r.'$' 回显匹配'abcab','^'。匹配r.'$' 恩迪夫 let[pattern,replacement,flags]=splita:command/ 让pattern=substitutepattern,'\\zm',EscapeRegexmatchingR,'g' 执行a:line1'.',a:line2.s/'.pattern'./'.replacement'./'.flags 端功能
在这之后,:'不确定这将如何转化为vim,但你可以看看。它使用负前瞻,我不认为你可以在vim中这样做,但希望它能让你走上正确的轨道vim确实有负前瞻,使用\@!修饰符。谢谢,但这将匹配foo{hello{}中的foo{hello{}再见}bar,不是吗?事实上,这提醒了我和一个朋友关于正式语言的一些讨论,他告诉我一些事情,比如你不能用正则表达式确定一组括号是否正确。这会使我的问题无法解决…是的,你的朋友是对的。使用正则表达式来正确匹配任意级别的嵌套括号是不可能的正则表达式。但是,可以构造一个正则表达式来匹配支持有限数量嵌套的正则表达式。我认为这个答案并没有试图这样做。好吧,那太好了,因为我认为里面不会有超过两对或三对括号。