2010-04-17 204 views
1

這是一個非常基本的正則表達式問題,但由於我似乎無法弄清楚爲什麼在某些情況下比賽失敗,我想我會發布它,看看是否有其他人可以指出我錯過了什麼。爲什麼我的正則表達式在數字以0結尾時失敗?

我試圖從形式的字符串拉出2套數字:

12309123098_102938120938120938 
1321312_103810312032123 
123123123_10983094854905490 
38293827_1293120938129308 

我用下面的代碼來處理每個字符串:

if($string && $string =~ /^(\d)+_(\d)+$/) { 
    if(IsInteger($1) && IsInteger($2)) { print "success ('$1','$2')"; } 
    else { print "fail"; } 
} 

凡IsInterger()函數如下:

sub IsInteger { 
    my $integer = shift; 
    if($integer && $integer =~ /^\d+$/) { return 1; } 
    return; 
} 

此函數似乎大多數時間工作,但失敗的隨從ng由於某種原因:

1287123437_1268098784380 
1287123437_1267589971660 

關於爲什麼這些失敗而其他人成功的任何想法?在此先感謝您的幫助!

+5

什麼你需要IsInteger功能?你的第一個正則表達式只會把一串數字放到'$ 1'和'$ 2'上,不需要測試這個。 if($ string =〜/ ^(\ d +)_(\ d +)/){print「success('$ 1','$ 2')」; } else {print「fail」; }' – ZyX 2010-04-17 17:01:35

+1

你爲什麼要寫'if($ string)'?你不需要這個。 – ZyX 2010-04-17 17:04:24

+0

@ZYZ - 好點。我繼續並更新了該功能。 – 2010-04-17 17:05:16

回答

3

這是來自unicornaddict和ZyX的答案附件:你想匹配什麼?

如果你想匹配'_'左右的序列,獨角獸成癮是正確的,你的正則表達式需要是^(\d+)_(\d+)$。此外,您還可以擺脫第一預選賽和「IsIntrger()的'功能完全 - 你已經知道這是一個整數 - 它匹配(\ d +)

if ($string =~ /^(\d+)_(\d+)$/) { 
    print "success ('$1','$2')"; 
} else { 
    print "fail\n"; 
} 

如果你想最後一個數字匹配並想知道爲什麼它失敗,這是IsInteger()if($intger &&)的第一個檢查。無論如何它是多餘的(你知道它是一個整數)並且在0上失敗,因爲正如ZyX所記錄的那樣 - 它的計算結果爲false。

同樣適用,但:

if ($string =~ /^(\d)+_(\d)+$/) { 
    print "success ('$1','$2')"; 
} else { 
    print "fail\n"; 
} 

給出的輸入12309123098_102938120938120938

0

不宜+列入分組:中

^(\d+)_(\d+)$代替^(\d)+_(\d)+$

3

因爲你在第二個字符串的結尾有0(\d)+提出只有最後一場比賽在$N變量,字符串"0"相當於假。

+0

@ZyX - 很好的解釋爲什麼這是失敗的。感謝您幫助我理解問題! – 2010-04-17 17:47:51

3

如有疑問這將輸出success ('8','8'),請檢查你的正則表達式是正式拍攝。

use strict; 
use warnings; 

my @data = (
    '1321312_103810312032123', 
    '123123123_10983094854905490', 
); 

for my $s (@data){ 
    print "\$1=$1 \$2=$2\n" if $s =~ /^(\d)+_(\d)+$/; 
    # Output: 
    # $1=2 $2=3 
    # $1=3 $2=0 
} 

您可能打算使用這兩種方法中的第二種方法。

(\d)+ # Repeat a regex group 1+ times, 
     # capturing only the last instance. 

(\d+) # Capture 1+ digits. 

此外,無論是在你的主循環和IsInteger(這似乎沒有必要,因爲在主迴路的初始正則表達式),你正在測試的真相,而不是更具體的東西,如definedlength。例如,零是一個有效的整數,但是是錯誤的。

0

很多人都在您的正則表達式,但你在你的IsInteger(你真的不需要你的例子)出現了問題。您檢查「真理」當你真的要檢查defined

sub IsInteger { 
    my $integer = shift; 
    if(defined $integer && $integer =~ /^\d+$/) { return 1; } 
    return; 
} 

你不需要大部分基礎設施在子程序雖然:

sub IsInteger { 
    defined $_[0] && $_[0] =~ /^\d+$/ 
} 
+0

定義爲+1,最後一部分爲-1:雖然你在技術上是正確的,但實際上解壓縮子程序參數會產生更清晰的代碼,並且我認爲在Perl已經很困難時勸阻有用的最佳實踐並不是一個好主意足以爲不熟悉的人閱讀。 – 2010-04-20 17:44:30

+0

解壓縮子程序參數並不總是提供更清晰或更好的代碼。這是您從中獲得額外價值的情況之一。當你不需要時,你正在做更多的實際工作,並創造更多的閱讀。如果你知道Perl,我的版本里沒有什麼是神祕的。如果你不懂Perl,請閱讀我的書籍:) – 2010-04-20 18:12:06

相關問題