Vim/sed展开方括号时如何正确匹配非行首[且不替换多余字符
Vim方括号格式化替换规则修正方案
你原有替换命令丢失前导字符的核心原因是:正则[^^]\[将[前的非行首字符纳入了匹配范围,替换时未保留这部分内容,才会把逗号等字符误删。
可用的完整替换命令
Vim支持正则零宽环视语法,匹配时不会消耗目标字符前后的内容,用它匹配「不在行首的[」就不会误改前导字符,修正后的命令可以直接使用:
:%s/^\[/\[\r/ | %s/\%(^\)\@<!\[/\r\[\r/g | %s/\]/\r\]/g
核心规则说明
- 问题修复的关键是
\%(^\)\@<!\[这段匹配规则:\%(^\)分组匹配行首位置,不生成捕获组、不占用额外资源\@<!是Vim正则的反向否定环视,代表「当前匹配位置的前面不能匹配前置分组的内容」,也就是限定匹配的[不能在一行的开头- 整个规则只会匹配
[本身,完全不会触碰[前面的逗号、引号等任何原有字符
- 其余两段替换逻辑和你原有设计一致:第一段给行首的
[后面加换行,第三段给所有]前面加换行。
旧版Vi兼容写法
如果遇到不支持环视语法的旧版Vi,可以用捕获组把[前面的字符保留下来,替换时原位放回即可,效果完全一致:
:%s/^\[/\[\r/ | %s/\([^^]\)\[/\1\r\[\r/g | %s/\]/\r\]/g
这里用\([^^]\)捕获[前面的非行首字符,替换时通过\1把捕获到的内容写回,同样不会丢失逗号等原有字符。
替换完成后直接执行你原本使用的gg=G命令即可自动调整缩进,最终输出完全符合预期格式,可以直接写入vim -e -c '执行命令'的Shell自动化脚本中。
内容的提问来源于stack exchange,提问作者Folaht
相关产品推荐
相关产品推荐

