Вы можете достичь этого с помощью НЕДОРОГОГО регулярного выражения.
Здесь, когда мы ловим имя, мы хотим «последовательность любого символа, за которой следует последовательность точек и пробелов». Итак, вот эквивалентное регулярное выражение: (.+)[. ]*
.
Но двигатель установлен в жадный режим по умолчанию. Что случится? Первая часть (.+)
не остановится на первой точке или первой найденной пробел. Зачем? Потому что можно выполнить все регулярные выражения до конца строки, и движок выберет этот путь, как в жадном режиме.
То же самое относится ко всему регулярному выражению, которое вы можете увидеть в рабочем коде ниже. Первая группа захвата будет захватывать за пределами поля имени.
Нам нужно сказать ему «съесть» менее подходящую часть.
<code><?php
$lines = '
John David James (DEM) . . . . . . 7,808 10.51
Marvin D. Scott (DEM) . . . . . . 6,548 9.55
Maria "Mary" Williams (DEM) . . . . 4,551 8.58
Dwayne R. Johnson. . . . . . . . 4,322 8.22
WRITE-IN. . . . . . . . . . . 188 .29
';
$lines = explode("\n", $lines);
// Here, the U flag sets the ungreedy mode
$pattern = '/^\s*(\S.+\S)[. ]+([0-9]+)(?:,([0-9]+))?\s.*$/U';
echo "<pre>";
foreach ($lines as $line) {
// Here : - ${1} will capture the name,
// - ${2} the integer part of the number
// - ${3} the decimal part
echo preg_replace($pattern, '${1},${2}${3}', $line) . "\n";
}
echo "
";
?>
Результат:
John David James (DEM),7808
Marvin D. Scott (DEM),6548
Maria "Mary" Williams (DEM),4551
Dwayne R. Johnson,4322
WRITE-IN,188