【问题标题】:How does Perl regexp anchor $ actually handle a trailing newline?Perl 正则表达式锚 $ 如何实际处理尾随换行符?
【发布时间】:2021-10-29 12:28:26
【问题描述】:

我最近在 Perl 正则表达式(OpenSuse 15.2 上的 Perl 5.26.1 x86_64)中发现了字符串结尾锚 $ 的一些意外行为。

据推测,$ 指的是 string 的结尾,而不是 grep(1) 中的 line 的结尾。因此,必须明确匹配字符串末尾的显式\n。但是,以下(完整)程序:

my @strings = ( 
  "hello world",
  "hello world\n",
  "hello world\t"
);
my $i = 0;
foreach (@strings) {
  $i++;
  print "$i: >>$_<<\n" if /d$/;
}

产生这个输出:

1: >>hello world<<
2: >>hello world
<<

即,/d$/ 不仅匹配三个字符串中的第一个,还匹配带有尾随换行符的第二个。另一方面,正如预期的那样,正则表达式 /d\n$/ 只匹配第二个字符串,/d\s$/ 匹配第二个和第三个。

这是怎么回事?

【问题讨论】:

    标签: regex perl end-of-line


    【解决方案1】:

    如前所述,$ metacharacter 确实匹配 string 的结尾,但也允许在字符串末尾的换行符之前匹配换行符。请注意,它还在多行字符串中的内部换行符之前与 /m global modifier 匹配

    还有一些方法可以微调精确匹配的内容,使用these assertions

    • \z 仅匹配字符串的结尾,即使带有/m 标志,但在末尾的换行符之前

    • \Z 仅匹配字符串的结尾,即使带有/m 标志,也匹配字符串末尾的换行符之前。就像$ 一样,除了它从不匹配(之前)多行字符串内部的换行符,甚至不匹配/m

    这些“零宽度”断言匹配位置,而不是字符。

    【讨论】:

      【解决方案2】:

      perlre 状态为 $ 元字符:

      匹配字符串的结尾
      (或字符串末尾的换行符之前;

      这意味着d 后面紧跟\n(换行符)将匹配正则表达式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-11
        • 2018-07-21
        • 1970-01-01
        • 1970-01-01
        • 2010-10-22
        相关资源
        最近更新 更多