1

我正在学习 perl 和正则表达式。以下代码:

my $data = "Bule beatles battling a blowing breeze";
my $results = $data =~ m/beatles battling/;
print "results: $results\n";

产生这个输出:

C:\scripts\perl\sandbox>regex.pl
results: 1

稍作改动,我就得到了我想要的结果:

print "results: $&\n";
results: beatles battling

我还注意到我不需要创建 $results:

my $data = "Bule beatles battling a blowing breeze";
$data =~ m/beatles battling/;
print "results: $&\n";

在我阅读的各种 perl 教程中,一些示例使用以下语法:

my $results = $data =~ m/string_to_match/;

我的问题:

  • 什么时候应该创建 $results 而不是直接对 $data 执行正则表达式?
  • 为什么我尝试打印 $data 时返回“1”?(我认为它正在返回匹配的长度......)
  • 创建 $results 有用吗?如果不是,我将如何处理多个结果?

例如:

my $data = "Bule beatles battling a blowing breeze";
my $results1 = $data =~ m/beatles/;
my $results2 = $data =~ m/battling/;

非常感谢 :)

4

2 回答 2

8

标量上下文中的正常正则表达式匹配返回一个布尔值,指示模式是否匹配。它不返回匹配的子字符串(效率低下!)。

要访问匹配的子字符串,请将模式括在括号中。然后,该模式的内容可在列表上下文$1中或作为第一个返回值使用:

my $data = "Bule beatles battling a blowing breeze";
my ($result) = $data =~ /(beatles battling)/;
say $result;

输出:beatles battling

如果您的模式中有更多捕获,它们的内容将在$2, $3, ... 中。您还可以通过列表上下文访问它们:

my ($substring, $beatles, $battling) = $data =~ /((beatles) (battling))/;

切勿使用$&,除非可能是在打高尔夫球时,或者在效率或良好风格不是问题的单班轮上。

$&etc. 的使用会在全局范围内对所有模式匹配产生开销。你不想要那个。

于 2013-07-07T19:40:12.017 回答
4

什么时候应该创建 $results 而不是直接对 $data 执行正则表达式?

有时,您想知道是否匹配,这(也回答了您的第二个问题)是什么1。因此,如果有匹配,你会得到10如果你没有得到任何匹配。

为什么我尝试打印 $data 时返回“1”?(我认为它正在返回匹配的长度......)

我相信我在上面回答了这个问题:)

创建 $results 有用吗?如果不是,我将如何处理多个结果?

我个人很少将值存储1或存储0在变量中。我猜一种可能的情况是,当您在包含一系列验证的函数中使用正则表达式,然后将此结果与其他验证的结果进行比较以得出该函数是否返回真(或有效与否) .

我发现自己在if(). 也许像...

if ($data =~ m/beatles/)
{
    # Do something
} else {
    # Do something else
}

对于您的示例:

my $data = "Bule beatles battling a blowing breeze";
my $results1 = $data =~ m/beatles/;
my $results2 = $data =~ m/battling/;

您可以比较$results1$results2得出结论,字符串是否$data同时包含单词beatlesand battling,字符串中的任何位置。

您可以阅读此页面来描述 perl 中的不同特殊变量,您会发现其中$&包含与最后一个模式匹配匹配的字符串。在您的示例中,在运行两个正则表达式后,您将得到$& = "battling"而不是beatles.

于 2013-07-07T19:51:33.620 回答