8

在 Perl SO answer中,张贴者使用此代码匹配空字符串:

$userword =~ /^$/; #start of string, followed immediately by end of string

brian d foy对此评论说:

你不能真的这么说,因为这将匹配一个特定的非空字符串。

问题:与哪个非空字符串匹配?它是仅由“”组成的字符串\r吗?

4

4 回答 4

9
use strict;
use warnings;

use Test::More;

ok("\n" =~ /^$/);
ok("\n" =~ /^\z/);
ok("\n" =~ /^\A\z/); # Better as per brian d. foy's suggestion

done_testing;

如果要测试字符串是否为空,请使用/^\z/或查看长度是否$str为零(这是我更喜欢的)。

输出:

好的 1
不行 2
不好 3
于 2012-04-18T17:34:41.270 回答
7

让我们检查一下文档,为什么不呢?引用perlre ,

$: 匹配行尾(或末尾换行符之前)

给定

\z: 仅在字符串末尾匹配

这意味着/^$/相当于/^\n?\z/

$ perl -E'$_ = "";    say /^$/ ||0, /^\n?\z/ ||0, /^\z/ ||0;'
111

$ perl -E'$_ = "\n";  say /^$/ ||0, /^\n?\z/ ||0, /^\z/ ||0;'
110

请注意,/m更改内容^$匹配。在 下/m^匹配任何“行”的开头,$匹配任何换行符之前和字符串末尾。

$ perl -E'$_ = "abc\ndef\n";  say "matched at $-[0]" while  /^/g'
matched at 0

$ perl -E'$_ = "abc\ndef\n";  say "matched at $-[0]" while  /$/g'
matched at 7
matched at 8

并使用 /m:

$ perl -E'$_ = "abc\ndef\n";  say "matched at $-[0]" while  /^/mg'
matched at 0
matched at 4   <-- new

$ perl -E'$_ = "abc\ndef\n";  say "matched at $-[0]" while  /$/mg'
matched at 3   <-- new
matched at 7
matched at 8

\A,\Z并且\z不受/m:

$ perl -E'$_ = "abc\ndef\n";  say "matched at $-[0]" while  /\A/g'
matched at 0

$ perl -E'$_ = "abc\ndef\n";  say "matched at $-[0]" while  /\z/g'
matched at 8

$ perl -E'$_ = "abc\ndef\n";  say "matched at $-[0]" while  /\Z/g'
matched at 7
matched at 8
于 2012-04-18T18:43:03.560 回答
3

正则表达式/^$/匹配非空字符串"\n"

默认情况下,Perl 正则表达式匹配假定字符串包含单“行”文本。

^匹配行首;在没有/m修饰符的情况下,这与字符串的开头相同。

$匹配行尾或末尾的换行符之前(这就是/^$/匹配非空字符串的原因"\n")。

报价perldoc perlre

默认情况下,“^”字符保证只匹配字符串的开头,“$”字符只匹配结尾(或结尾的换行符之前),Perl 在假设字符串只包含一条线。嵌入的换行符不会被“^”或“$”匹配。但是,您可能希望将字符串视为多行缓冲区,这样“^”将匹配字符串中的任何换行符(除非换行符是字符串中的最后一个字符),而“$”将在任何换行符之前匹配。以更多开销为代价,您可以通过在模式匹配运算符上使用 /m 修饰符来做到这一点。

于 2012-04-18T19:02:14.340 回答
1

脚本:

my $str = "\n";

my $test1 = ($str =~ /^$/)   ? 1 : 0;
my $test2 = ($str =~ /\A\z/) ? 1 : 0;

print "$test1, $test2\n";

输出:

1, 0
于 2012-04-18T19:16:58.947 回答