【问题标题】:Perl regex: when to use $&Perl 正则表达式:何时使用 $&
【发布时间】:2013-07-08 03:51:33
【问题描述】:

我正在学习 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/;

非常感谢:)

【问题讨论】:

    标签: regex perl


    【解决方案1】:

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

    要访问匹配的子字符串,请将模式括在括号中。该模式的内容随后在$1 中可用,或作为list context 中的第一个返回值:

    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))/;
    

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

    $& 等的使用会在全局范围内对所有模式匹配施加开销。你不想这样。

    【讨论】:

      【解决方案2】:

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

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

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

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

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

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

      我发现自己在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 是否在字符串的任何位置都包含单词beatlesbattling

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

      【讨论】:

      • 没有提到捕获组?
      • @mob amon 在我写这个答案时已经在他的回答中提到了这些;我不想重复他说的话,恐怕我对 perl 的了解还不够多,无法提及更多……
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多