gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 07:39:52 24 4
gpt4 key购买 nike

Perl 版本:5.16.01

我正在读一本基于 perl 5.8 的关于正则表达式的书

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

code:
$text = "c\n\n\n\n\nb";
$text =~ s/^\s*$/<p>/mg;
print "$text";

结果如下:

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


我想知道为什么我没有得到一个 <p>但在“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"};

输出 <"Prematch" - "Match" - "Postmatch"> :

<"c\n" - "\n\n" - "\nb">
<"c\n\n\n" - "" - "\nb">
Result: "c\n<p><p>\nb"

基本上,正则表达式从位置 2 到 4 匹配,捕获 2 个返回字符。替换后,它从位置 4 开始搜索并匹配零宽度模式,因此添加第二个 <p> .

这不直观的原因之一是我们的正则表达式替换了 \n\n在位置 2 和 3 带有 <p> .然而,lookbehind 断言(^ 是特殊变体)将字符串视为它原来的样子,而不是因为它可能已被以前的 /g 传递所取代。正则表达式。因此,在位置 4 匹配时,正则表达式会看到 c\n\n\n在它后面而不是 c\n<p> (如我们上面的输出所示),因此将匹配 ^再次$紧挨着它,中间没有间距。

解决方案是使用 + 不允许零宽度模式在这种情况下而不是 * .

次要示例

另一个例子是下面这个更简单的正则表达式

my $text = "caab";

$text =~ s/a*/<p>/g;
print $text;

输出:

<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

因此,最后一课就是要警惕匹配零宽度模式的正则表达式。

关于regex - 尝试使用/^\s*$/匹配多个空行并替换它们失败并得到令人困惑的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23259403/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com