regex - perl 正则表达式从字符串 : why does it work? 中删除初始全空白行

标签 regex perl whitespace regex-greedy modifier

正则表达式 s/\A\s*\n// 从字符串的开头删除每个全空白行。 它保留所有其他内容,包括可能开始第一条可见行的任何空白。 “可见线”是指满足 /\S/ 的线。 下面的代码演示了这一点。

但是它是如何工作的呢?

\A 锚定字符串的开头

\s* 贪婪地捕获所有空白。但是没有(?s)修饰符,它应该在第一行的末尾停止,不是吗? 看 https://perldoc.perl.org/perlre .

假设没有 (?s) 修饰符,它仍然“将字符串视为单行”。 然后我希望贪婪的 \s* 捕获它看到的每个空白字符, 包括换行符。所以它会传递“dogs”字符串之前的换行符,继续抓取空格,遇到“d”,我们将永远无法匹配。

不过,代码完全符合我的要求。因为我无法解释它,所以它就像一个拼凑,碰巧有效的东西,通过反复试验发现的。它起作用的原因是什么?

#!/usr/bin/env perl 
use strict; use warnings;
print $^V; print "\n";

my @strs=(
    join('',"\n", "\t", ' ', "\n", "\t", ' dogs',),
    join('',
              "\n",
              "\n\t\t\x20",
              "\n\t\t\x20",
    '......so what?',
              "\n\t\t\x20",
    ),
);

my $count=0;
for my $onestring(@strs)
{
    $count++;
    print "\n$count ------------------------------------------\n"; 
    print "|$onestring|\n";
    (my $try1=$onestring)=~s/\A\s*\n//;
    print "|$try1|\n";
}

最佳答案

But how does it work?
...
I would expect the greedy \s* to grab every whitespace character it sees, including linefeeds. So it would pass the linefeed that precedes the "dogs" string, keep grabbing whitespace, run into the "d", and we would never get a match.

正确——\s* 一开始会抓取 d 之前的所有内容(在 dogs 中),这样匹配就会失败...所以它备份,一次一个字符,缩短贪婪的抓取,以便有机会匹配以下模式,此处为 \n

那行得通!所以 \s* 匹配到(最后一个!)\n,那个与模式中的以下 \n 匹配,并且一切都很好。这已被删除,我们保留打印的 "\tdogs"

这叫做 backtracking .另见 in perlretut .可以抑制回溯,最显着的是 possesive forms (如 \w++ 等),或者更确切地说是通过扩展结构 (?>...) .


But without the (?s) modifier, it should stop at the end of the first line, should it not?

这里你可能会混淆\s.,它确实不匹配\n(没有/s)

关于regex - perl 正则表达式从字符串 : why does it work? 中删除初始全空白行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69559891/

相关文章:

JavaScript:好的部分 白色空间铁路图令人困惑

swift - 为什么 Swift 的三元运算符对空格如此挑剔?

python - URI 正则表达式模式匹配

java - 匹配 INI 节 block

regex - 如何在字母字符和数字字符之间插入空格?

linux - 没有 shebang 行的 Shell 脚本工作正常吗?为什么?

python re match exact only only occurrence(没有重复连续)

Java 属性文件

perl - 如何在perl中删除文件的最后10行

bash - 如何循环遍历两个目录中的文件名排序列表