2017-02-24 55 views
0

我需要打印perl中存储的所有匹配的字符串。我看到的这个 Print the matched string using perl Perl Regex - Print the matched value在perl中打印匹配的字

各个岗位和我尝试先尝试打印的第一个字。但我得到一个生成错误

Use of uninitialized value $1 in concatenation (.) or string at rg.pl line 10. 

我已经试过拆分和数组,它的工作原理,但打印$ 1时,它会引发错误。

我的代码是在这里

#!/usr/bin/perl/ 
use warnings; 
use strict; 


#my $line = "At a far distance near the bar, was a parked car. Star were shining in the night. The boy in the car had scar and he was at war with his enemy. \n"; 

my $line = "At a far distance near the bar, was a parked car. \n"; 
if($line =~ /[a-z]ar/gi) 
{  print "$1 \n"; } 

$_ = $line; 

我想我对这段代码的输出是

far 

,并随后打印包含AR的所有单词,

far 
near 
bar 
parked 
car 

我甚至尝试改变我的代码,如下,但没有奏效,同样的错误

if($line =~ /[a-z]ar/gi) { 
     my $match = $1; 
     print "$match \n"; } 

回答

2

首先,你没有捕获任何东西,这是$n变量是如何填充。把括号围绕要被捕获到$1

if ($line =~ /([a-z]ar)i/) { print "$1\n" } 

我已经删除了/g这是不必要在这里。

接下来,您将在文字ar之前提供一个字母的模式。这不会捕获near,也不会捕获parked。它甚至不会匹配开始ar的单词,因为它要求在ar之前有一个字母。您需要使用quantifiers。你也想找到所有匹配。

一种方式是通过提供列表context/g全球)修改舀它们加起来

my @words = $line =~ /([a-z]*ar[a-z]*)/gi; 

print "$_\n" for @words; 

[a-z]*意味着匹配字母,零或更多的时间。所以一个可选的字符串。 /g使它匹配字符串中的所有这些模式。在列表上下文中返回匹配列表。

或者,您可以在标量上下文匹配像在第一个例子,但在while循环

while ($line =~ /([a-z]*ar[a-z]*)/gi) { print "$1\n" } 

这里/g做不同的东西。它匹配一次模式并返回true,while条件为真,我们打印。然后它回来并寻找比赛从它匹配的地方以前 ...并继续这样做,直到没有更多的比赛。

这是完全复杂的行为。 From Regexp Quote-Like Operators in perlop

/g修饰符指定全局模式匹配 - 即在字符串内匹配尽可能多的次数。它的行为方式取决于上下文。在列表上下文中,它返回正则表达式中任何捕获括号所匹配的子字符串列表。如果没有括号,它会返回所有匹配字符串的列表,就好像整个模式中都有括号一样。

在标量环境中,m//g的每次执行都会找到下一个匹配项,如果匹配则返回true,如果没有进一步匹配则返回false。   [...]

阅读关于这个更详细和教程的方式in perlretut,在 “全局匹配”。

+0

您能否多给点解释一下,这两种工作方式有什么不同? if($ line =〜/([a-z] ar)i /){print“$ 1 \ n”} if($ line =〜/ [a-z] ar/gi) {print“$ 1 \ n”; } –

+0

一个是全局匹配('g'),另一个不是。 –

+0

不,我的意思是捕捉部分你最近怎么样? –

2

对于多个匹配项,请使用while循环。另外,我用圆括号包围了要捕获的数量,以表明它是一个捕获组。

while ($line =~ /([a-z]*ar[a-z]*)/gi) { 
    print "$1 \n"; 
} 
+0

谢谢,这很有帮助。你在这里使用替代吗? s ////没有得到那部分。 –

+0

这个'/([a-z] + ar)/'不会捕获'parked',也不会匹配_start_和'ar'(它需要'ar'之前的一个字母)。 – zdim