2014-06-24 133 views
1

我有一個字符串,可以讀取像這樣的東西(雖然不總是,數字可能會有所不同)。爲什麼這個正則表達式在Perl中不匹配?

Board Length,45,inches,color,board height,8,inches,black,store,wal-mart,Board weight,20,dollars 

我想匹配董事會長度這個正則表達式後面的45。

if ($string =~/Board Length,(\d+\.\d+)/){ 

    print $string; 

} 

格式是否錯誤?我認爲d +會根據需要匹配儘可能多的數字。會匹配一個文字'。',並且d +會匹配小數點後的任何數字(如果有的話)。

回答

2

正如你所說的,十進制的.和後面的數字是強制性的。因此(\.\d+)?使它可選,

if ($string =~/Board Length,(\d+(?:\.\d+)?)/) 
2

你是絕對正確的,應該匹配什麼。但是,沒有'?'字符,你指定所有這些片段必須存在。

\d+\.\d+ 

這意味着 「1個或多個號碼,期間,1個或多個數字」

1.5,253333.7,0.0將所有匹配。但是,您的示例使用45,它沒有「。」在它之後,也沒有數字。有幾個解決方案可以解決您的問題,其中最充分的證據是由mpapac在上面陳述的。允許小數和後面的數字是可選的。

(\.\d+)? 

與此相同的問題是放置一個()使其成爲另一個捕獲組。你可能會也可能不想要這個。把它放在裏面意味着「把它作爲一個組來使用,但不要捕獲它。」因此:

(?:\.\d+)? 

另一種選擇是不要做分組,而是使兩個小數本身可選的數字小數點後零或更多,而不是一個或多個。這看起來像這樣:

\d+\.?\d* 
1

您不打印您捕獲的內容。您正在打印$_,我們不知道它是什麼。

if ($string =~/Board Length,(\d+\.\d+)/){ 
    print $_; 
} 

我想你想的是:

if ($string =~/Board Length,(\d+\.\d+)/){ 
    print $1; 
} 
+0

呀測試,我結束了沒收了一下後,我張貼了這個。謝謝。 – user1768884

0

您有以下表現:

$string =~/Board Length,(\d+\.\d+)/

你的字符串是這樣的:

Board Length,45,inches 

字符串會匹配模式Board Length,。但是,我們的模式的其餘部分匹配一個或多個數字,後跟一個句點後跟一個或多個數字。這與字符串45不匹配。那裏沒有小數。

問題是你想要匹配什麼。例如,如果數由逗號包圍,你可以這樣做:

$string =~ /Board Length,([^,]+),/; 
my $number = $1; 

[^,]意味着不是逗號。你將逗號後的所有內容捕獲到下一個逗號。這將允許您捕獲45,45.32,甚至4.5e+10。只是兩個逗號之間的任何東西。

請注意,您爲第一個捕獲組使用$1而不是$_

另一種方法是使用非貪婪匹配:

$string =~ /Board Length,(.+?),/; 
my $number = $1; 

如果什麼被捕獲的不是數字,會發生什麼?您可以使用從Scalar::Utillooks_like_number功能(已包含在Perl分發了很長時間):

use Scalar::Util qw(looks_like_number); 

my $string = "Board Length,Extra long,feet,..."; 
... 
$string =~ /Board Length,(.+?),/; 
my $number = $1; 

if (looks_like_number($number)) { 
    print "$number is a number\n"; 
} 
else { 
    print "Nope. $number isn't a number\n"; 
} 
相關問題