VIM 7.2使用`:perldo`和多个表达式编写脚本问题

Eva*_*oll 7 vim scripting perl

后台任务

为了消除XY问题,我会说我在做什么:我正在尝试:perldo在VIM 7.2中完成两项任务:

  • 清除所有尾随空格,包括(清除不删除)只有空格的行
    • s/\s+$//;
  • 删除第一个非空格字符之前存在的非制表符空格
    • s/^ (\s*) (?=\S) / s#[^\t]##g;$_ /xe;

我想一次性完成这一切.目前,使用:perldo,我可以通过两次通过.(通过使用:perldo两次)

该命令应如下所示:

:perldo s/\s+$//; s/^ (\s*) (?=\S) / s#[^\t]##g;$_ /xe;
Run Code Online (Sandbox Code Playgroud)

Perl背景

为了理解这个问题,您必须了解一点Perl s///自动绑定到$_正则表达式可以自由修改的默认变量.大多数核心功能$_默认运行.

perl -e'$_="foo"; s/foo/bar/; s/bar/baz/; print' #将打印 baz

假设您可以使用:perldoVIM 链接表达式,并且它可以在逻辑上工作.

VIM不太好

现在我的VIM问题可以用代码更好地证明 - 我把它简化为一个简单的测试.打开一个新缓冲区,将以下文本放入其中:

aa bb
aa
bb
Run Code Online (Sandbox Code Playgroud)

现在运行此:perldo s/a/z/; s/b/z/;缓冲区现在具有:

za zb
aa
zb
Run Code Online (Sandbox Code Playgroud)

为什么第一行正则表达式在第二行不成功,而第二个正则表达式本身是成功的,并且在第一行?

Bri*_*per 6

看来,传递给它的整个Perl表达式:perldo必须返回一个真/定义的值,否则每行都会丢弃结果.

试试这个,任何一行都没有发生:

:perldo s/a/z/; s/b/z/; 0
Run Code Online (Sandbox Code Playgroud)

试试这个,它可以按预期在所有3行上运行:

:perldo s/a/z/; s/b/z; 1
Run Code Online (Sandbox Code Playgroud)

:perldo文档中的一个示例提示:

:perldo $_ = reverse($_);1
Run Code Online (Sandbox Code Playgroud)

但不幸的是,它没有明确说明发生了什么.


mob*_*mob 5

不知道究竟:perldo做了什么,但如果你运行的话

:perldo s/a/z/+s/b/z/
Run Code Online (Sandbox Code Playgroud)

然后你会得到更像你期望的东西.