У меня есть эта строка:
$string = 'Hello IV WorldX';
И я хочу заменить все римские цифры на целые числа.
У меня есть следующая функция для преобразования римского в целое число:
function roman2number($roman){
$conv = array(
array("letter" => 'I', "number" => 1),
array("letter" => 'V', "number" => 5),
array("letter" => 'X', "number" => 10),
array("letter" => 'L', "number" => 50),
array("letter" => 'C', "number" => 100),
array("letter" => 'D', "number" => 500),
array("letter" => 'M', "number" => 1000),
array("letter" => 0, "number" => 0)
);
$arabic = 0;
$state = 0;
$sidx = 0;
$len = strlen($roman);
while ($len >= 0) {
$i = 0;
$sidx = $len;
while ($conv[$i]['number'] > 0) {
if (strtoupper(@$roman[$sidx]) == $conv[$i]['letter']) {
if ($state > $conv[$i]['number']) {
$arabic -= $conv[$i]['number'];
} else {
$arabic += $conv[$i]['number'];
$state = $conv[$i]['number'];
}
}
$i++;
}
$len--;
}
return($arabic);
}
echo roman2number('IV');
Прекрасно работает (попробуйте на ideone). Как мне искать & заменить через строку, чтобы заменить все экземпляры римских цифр. Что-то вроде:
$string = romans_to_numbers_in_string($string);
Похоже, что на помощь должно прийти регулярное выражение … или?
Вот простое регулярное выражение для соответствия римским цифрам:
\b[0IVXLCDM]+\b
Итак, вы можете реализовать romans_to_numbers_in_string следующим образом:
function romans_to_numbers_in_string($string) {
return preg_replace_callback('/\b[0IVXLCDM]+\b/', function($m) {
return roman2number($m[0]);
},$string);
}
Есть некоторые проблемы с этим регулярным выражением. Например, если у вас есть такая строка:
I like roman numerals
Это станет:
1 like roman numerals
В зависимости от ваших требований, вы можете оставить это, или вы можете изменить регулярное выражение так, чтобы оно не преобразовывало единичные числа в числа.
Других решений пока нет …