Regex 尝试使用/^\s*$/匹配多个空行并替换它们失败,结果令人困惑

Regex 尝试使用/^\s*$/匹配多个空行并替换它们失败,结果令人困惑,regex,perl,Regex,Perl,Perl版本:5.16.01 我正在读一本关于基于Perl5.8的正则表达式的书 这本书说,s/^\s*$/blabla/mg可以匹配和替换多个空行。 但当我练习时,我得到了一个令人困惑的结果 code: $text = "c\n\n\n\n\nb"; $text =~ s/^\s*$/<p>/mg; print "$text"; 代码: $text=“c\n\n\n\n\nb”; $text=~s/^\s*$//mg; 打印“$text”; 结果如下: C:\Users\Ad

Perl版本:5.16.01

我正在读一本关于基于Perl5.8的正则表达式的书

这本书说,
s/^\s*$/blabla/mg
可以匹配和替换多个空行。 但当我练习时,我得到了一个令人困惑的结果

code:
$text = "c\n\n\n\n\nb";
$text =~ s/^\s*$/<p>/mg;
print "$text";
代码:
$text=“c\n\n\n\n\nb”;
$text=~s/^\s*$//mg;
打印“$text”;

结果如下:

C:\Users\Administrator\Desktop\regex>perl t2h.pl 
c
<p><p>
b
C:\Users\Administrator\Desktop\regex>perl t2h.pl
C

B


我想知道为什么我没有得到一个
,而是在'c'和'b'之间得到两个。Perl的
/$/
在5.8版之后是否会发生变化?

这里的教训是要警惕将匹配零宽度模式的正则表达式,否则可能会得到意外的结果

我们可以通过显示两名替补球员的赛前、赛后和赛后情况来了解发生了什么:

use strict;
use warnings;

my $text = "c\n\n\n\nb";

$text =~ s{^\s*$}{
    printf qq{<"%s" - "%s" - "%s">\n}, map s/\n/\\n/gr, ($`, $&, $');
    "<p>"
}emg;

$text =~ s/\n/\\n/g;
print qq{Result: "$text"};
产出:

<p>c<p><p>b<p>

因此,最后一个教训就是要小心匹配零宽度模式的正则表达式。

Quantifier*匹配0次或更多次, 量词?匹配1次或多次

因此,您的正则表达式应该写成
s/^\s+$//mg

您可以尝试以下方法:

#!/usr/bin/perl
$text = "c\n\n\n\n\nb";
$text =~ s/[\r\n]//g;
print $text;

演示

关于“我不知道它为什么要这样做”,为什么不呢?您要求它匹配从
b
开始的零个(或更多)空格字符,结果它匹配了。(然后你让它再做一次,它说“不,哈,我不匹配同一件事两次”,所以它看了看
b
)@ikegami这不是一个解释。当我问一些事情来计算我有多少只手时,我可以理解地期望答案是2。我不希望答案是2和0,0和0。是的,两者都是正确的,但第二个是多余的。不过,我确实欢迎您对这背后的逻辑进行真正的解释。您没有要求计数手,而是要求替换从位置3开始的0+空格。事实证明它确实可以匹配,所以它会按照你的要求替换匹配。数手应该是
“habah”=~/h/g
,而不是
“habah”=~/h*/g
好的,我愿意上船。原因是它是位置匹配。首先它在位置0匹配,然后是1,然后是3,最后是4。尽管位置1和3最终是相邻的,但它们仍然匹配,因为正则表达式允许零宽度模式。谢谢你的回答,但我只想知道为什么会有双“”。
<p>c<p><p>b<p>
0 c - match a zero width pattern
1 a - Match a 2 character pattern
2 a
3 b  - Match a zero width pattern
4 $ - match a zero width pattern
#!/usr/bin/perl
$text = "c\n\n\n\n\nb";
$text =~ s/[\r\n]//g;
print $text;