这个 vim 正则表达式有什么问题?

What is wrong with this vim regular expression?

我有一个扩展名为 .elf 的文件列表

file1.elf file2.elf file3.elf

我正在尝试在 shell 中使用 运行 命令(例如 run file1.elf >file1.log)对它们进行 运行,并将结果保存在一个日志文件中,文件名加上 .log。 我的文件列表非常大。我正在尝试 vim 正则表达式,以便它将匹配文件名,例如 file1.elf 中的 file1,并使用它来创建日志文件的名称。我正在尝试这样

s/\(\(\<\w\+\)\@<=\.elf\)/ >\.log/

我在这里尝试匹配由 .elf 开始的文本并将其保存在 中,我希望整个文件名都在其中,我希望 将只包含文件名减去扩展名。但这给了我 run file1 >file1.run 没有使用完整的文件名,它有一些遗漏的 .elf 扩展名。我可以 \.elf 来获得正确的结果,但我想知道为什么表达式没有按预期工作?

\@<= 似乎毫无意义且不需要。删除它可以获得所需的行为。

您在匹配模式中使用了 \@<=。这是 positiv lookahead 断言。根据文档 (:help /\@<=1),

Matches with zero width if the preceding atom matches just before what follows

重要的部分是它匹配零宽度,这就是你正在经历的,.elf(后面)匹配但宽度为零,因此 </code> 不包含后缀 <code>.elf.

相反,使用

会更容易
%s/\v(.*)\.elf$/run .elf > .log/

在这里,我用\v开启了非常神奇(:help magic)。启用此功能后,您在使用分组括号时不需要所有这些反斜杠。

然后是(.*)匹配并存储文件名直到

\.elf$ 好像是每个文件的后缀。

在替换部分,在 / 之后添加文字 run,然后添加 </code>。 <code> 将被存储的文件名替换(没有 .elf 后缀)。