2017-02-24 81 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