Perl在正则表达式替换的过程中忽略空格。

3
假设我有一个字符串$str = "onetwo"
我想写一个正则表达式替换命令,忽略空格(这样更易读):
$str =~ s/
          one
          two
         /
          three
          four
         /x

"threefour" 不同,这会生成 "\nthree\nfour\n"(其中 \n 是换行符)。基本上,/x 选项会忽略匹配替换的一侧的空格,但不会忽略替换的另一侧。如何在替换侧也忽略空格?


如果你想要“可读性强”的代码,那就远离正则表达式。 - Ken Browning
@Ken,你可能只是半开玩笑,但我正在处理一个非常复杂的正则表达式,需要随着时间进行管理,例如在这里描述的那样(http://www.perl.com/pub/2004/01/16/regexps.html)。 - Alan Turing
6
@Ken Browning,简单的正则表达式模式可以写得很清晰易懂,而更复杂的正则表达式模式需要大量非正则表达式代码才能实现,因此避免使用正则匹配并不能使事情更易读。一个常见错误是人们忘记了替代方案并没有更易读。像其他任何东西一样,记录你的正则表达式模式中的复杂部分,就可以做到这一点。 - ikegami
1个回答

12

s{...}{...} 基本上等同于 s{...}{qq{...}}e。如果你不想要 qq{...},你需要用其他的东西来替换它。

s/
   one
   two
/
   'three' .
   'four'
/ex

甚至可以这样:
s/
   one
   two
/
   clean('
      three
      four
   ')
/ex

一个可能的实现 clean 的方法是:
sub clean {
    my ($s) = @_;
    $s =~ s/^[ \t]+//mg;
    $s =~ s/^\s+//;
    $s =~ s/\s+\z//;
    return $s;
}

1
@DVK,你说的性能惩罚是什么?难道你认为/e是“eval EXPR”吗?不,它不涉及运行时解析和编译。所以只剩下了'threefour'与'three' . 'four'之间的区别。后者被常量折叠成前者,所以我不知道你为什么认为会有性能惩罚。 - ikegami
@ikegami,您能简要记录一下“clean”的可能实现方式吗?顺便说一句,这个想法非常棒。 - Alan Turing
1
@DVK,/e版本需要多0.000,000,6秒。这甚至不到一纳秒。 - ikegami
2
@Lex Fridman,实际上它有很多漏洞,所以我替换了它。发布的版本应该是有用的。1)从每行中删除前导空格。2)删除前导空白行。3)删除尾随空白行。 - ikegami

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接