为什么 ex (vim) 将匹配模式捕获到行尾

Why ex (vim) is catching matching pattern to the end of line

文件包含以下行:

[assembly: AssemblyVersion("1.0.0.0")]

Bash 将一个版本替换为另一个版本的脚本:

echo "%s/AssemblyVersion\s*\(.*\)/AssemblyVersion(\"$newVersionNumber\")]/g
        w
        q
        " | ex $filePath

问题是为什么这会把整行都抓到最后,所以我必须在替换字符串的末尾添加 ]

出现问题是因为.*将所有字符匹配到行尾,并且\(\)创建了一个捕获组(与大多数 NFA 正则表达式引擎不同,Vim 正则表达式在模式中将 ( 字符与未转义的 () 与未转义的 ) 匹配)。

您可以使用

%s/AssemblyVersion\s*([^()]*)/AssemblyVersion(\"$newVersionNumber\")/g

在这里,AssemblyVersion 将匹配单词,然后 \s* 将匹配任何 0+ 空白字符,( 将匹配文字 ([^()]* 将匹配 () 以外的 0+ 个字符,而 ) 将匹配文字 ).

您可以使用的另一个正则表达式替换命令是

:%s/AssemblyVersion\s*(\zs[^()]*\ze)/\"$newVersionNumber\"/g

在这里,AssemblyVersion\s*( 将匹配 AssemblyVersion,0+ 个空格,(\zs 将从匹配中省略该部分,然后是 [ 以外的 0+ 个字符=15=] 和 ) 将匹配,然后 \ze) 将检查当前位置右侧是否有 ),但不会将其添加到匹配中。

\zs 将下一个字符设置为匹配的第一个字符。 \zs 模式之前的任何文本都不会包含在匹配项中。

\ze 设置匹配结束。 \zs 模式之后的任何内容都不会成为匹配的一部分。