2010-05-12 47 views
1

我正在嘗試preg_match與羅馬數字整數轉換器。問題在於,對於某些輸入,preg_replace似乎給出的匹配太少。代碼:php的preg_match返回不同數量的匹配相同的模式

function romanNumeralToInt($romanNumeral) 
{ preg_match 
    ( '/^(M?M?M?)' 
     .'((CM)|(CD)|((D?)(C?C?C?)))' 
     .'((XC)|(XL)|((L?)(X?X?X?)))' 
     .'((IX)|(IV)|((V?)(I?I?I?)))$/', $romanNumeral, $match); 
    print_r($match); 

    $result=0; 
    $result += 1000*strlen($match[1]); 
    if(strlen($match[3]) != 0){$result += 900;} 
    if(strlen($match[4]) != 0){$result += 400;} 
    if(strlen($match[5]) != 0) 
    { $result += 100*strlen($match[7]) + 500*strlen($match[6]); 
    } 
    if(strlen($match[9]) != 0){$result += 90;} 
    if(strlen($match[10]) != 0){$result += 40;} 
    if(strlen($match[11]) != 0) 
    { $result += 10*strlen($match[13]) + 50*strlen($match[12]); 
    } 
    if(strlen($match[15]) != 0){$result += 9;} 
    if(strlen($match[16]) != 0){$result += 4;} 
    if(strlen($match[17]) != 0) 
    { $result += 1*strlen($match[19]) + 5*strlen($match[18]); 
    } 

    return $result; 
} 

echo romanNumeralToInt("XXVIII"); // gives correct results 

但在「IV」結尾的羅馬數字將切斷的最後3場比賽($比賽將只包含元素0-16而非完整0-19),以及任何類似羅馬數字以「IX」結尾將會截斷最後4場比賽。

這是預期的行爲,還是我的PHP錯誤?

+0

而不是使用正則表達式,你可以嘗試http://pear.php.net/package/Numbers_Roman/。 – 2010-05-12 07:36:57

+0

不是我要做的,我正在用正則表達式使用羅馬數字作爲excersize。感謝壽。 – 2010-05-12 23:09:48

回答

1

我希望這是預期的行爲。 =)

正則表達式嘗試匹配OR基從左至右,只要它找到一個匹配停止,所以它永遠不會嘗試,如果它發現一個IV或IX匹配那些過去三或四個組。其實,我認爲,如果你的表情包含CM或XL或類似的東西,其他一些條目也會丟失。

我發現使用RegExr有助於調試正則表達式。使用這個爲你的正則表達式,一些組捕獲空字符串,並且一些組包含NO MATCH。

+0

測試過的CM和XL也不會發生在他們身上(我也有過這種想法)。 +1爲RegExr,這是一個不錯的工具。它有點奇怪,它會忽略最後幾場比賽。 – 2010-05-12 08:07:13

相關問題