preg_match в php возвращает различное количество совпадений для одного и того же шаблона - PullRequest
1 голос
/ 12 мая 2010

Я пробую preg_match с преобразованием римской цифры в целое число. Проблема в том, что для определенных входных данных preg_replace, похоже, дает слишком мало совпадений. Код:

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 совпадения ($ match будет содержать только элементы 0-16, а не полные 0-19), и аналогично любая римская цифра, заканчивающаяся на «IX», обрежет от последних 4 матчей.

Это ожидаемое поведение или мой PHP глючит?

1 Ответ

1 голос
/ 12 мая 2010

Я ожидаю, что это ожидаемое поведение. =) * * Тысяча одна

Regex пытается сопоставить группы OR слева направо, останавливаясь, как только находит совпадение, поэтому он никогда не будет пытаться сопоставить эти последние три (или четыре) группы, если найдет IV или IX.

На самом деле, я думаю, что если ваше выражение содержит CM или XL или что-то в этом роде, некоторые другие записи тоже будут отсутствовать.

Я считаю, что использование RegExr очень помогает при отладке регулярных выражений. Используя это для вашего регулярного выражения, некоторые группы перехватывают пустые строки, а некоторые группы содержат NO MATCH.

...