Regex 为什么ex(vim)将匹配模式捕捉到生产线末端

Regex 为什么ex(vim)将匹配模式捕捉到生产线末端,regex,vim,ex,Regex,Vim,Ex,文件包含以下行: [assembly: AssemblyVersion("1.0.0.0")] 将一个版本替换为另一个版本的Bash脚本: echo "%s/AssemblyVersion\s*\(.*\)/AssemblyVersion(\"$newVersionNumber\")]/g w q " | ex $filePath 问题是为什么要将整行捕获到末尾,所以我必须在替换字符串的末尾添加]?问题的出现是因为*将所有字符匹配到行的末尾,并

文件包含以下行:

[assembly: AssemblyVersion("1.0.0.0")]
将一个版本替换为另一个版本的Bash脚本:

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

问题是为什么要将整行捕获到末尾,所以我必须在替换字符串的末尾添加
]

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

你可以用

%s/AssemblyVersion\s*([^()]*)/AssemblyVersion(\"$newVersionNumber\")/g
这里,
AssemblyVersion
将匹配单词,然后
\s*
将匹配任何0+空格字符,
将匹配一个文本
[^()]*
将匹配除
之外的0+字符,
)将匹配一个文本

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

:%s/AssemblyVersion\s*(\zs[^()]*\ze)/\"$newVersionNumber\"/g
在这里,
AssemblyVersion\s*(
将匹配
AssemblyVersion
,0+空格和
\zs
将从匹配中忽略该部分,然后将匹配
)以外的0+字符
),然后
\ze)
将检查是否存在
位于当前位置的右侧,但不会将其添加到匹配项中

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


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

这是因为
*
将所有字符匹配到结尾,将其替换为
[^]]*
并且您不必在替换中添加
]
。这是一个贪婪的正则表达式,不会停在
上吗?是的,
*
[^]]*
是贪婪的,因为
*
是贪婪的量词,它们都匹配
,但是
匹配任何字符,
[^]]
匹配任何字符,但是
]
.Hmm,如果
*
捕捉到了
,那么在正则表达式中明确指定的
会发生什么?我已经发布了答案:)并添加了一个较短的选项。