PHP preg заменяет несколько правил
Мне просто интересно, как применить несколько правил для preg_replace, не выполняя их в первом запуске. Это немного сложно, позвольте мне объяснить на примере.
Ввод:
$string = 'The quick brown fox jumps over the lazy freaky dog';
Правила:
- заменить a, я ... , o с u (если не в начале слова и если не перед / после гласной)
- заменить e, u с i (если не в начале слова и если нет до / после гласной)
- заменить ea на i (если не в начале слова)
- замените целые слова ie dog на cat и fox на wolf (без применения правил выше)
Вывод: Thi quick bruwn wolf jimps over thi luzy friky cat
Я начал с чего-то вроде этого: (отредактировано благодаря Ezequiel Muns )
$patterns = array();
$replacements = array();
$patterns[] = "/(?<!b|[aeiou])[aio](?![aeiou])/";
$replacements[] = "u";
$patterns[] = "/(?<!b|[aeiou])[eu](?![aeiou])/";
$replacements[] = "i";
$patterns[] = '/ea/';
$replacements[1] = 'i';
$patterns[] = '/dog/';
$replacements[0] = 'cat';
echo preg_replace($patterns, $replacements, $string);
Вывод:
Thi qiick briwn fix jimps ivir thi lizy friiky dig
отредактировано:
Как вы можете видеть, проблема заключается в том, что каждое правило перезаписывается предыдущим правилом.Пример ' Фокс':
- правило: превращает fox в fux
- правило: превращает fux в fix
Есть ли способ избежать следующего правила(правил), если символ уже был введен предыдущим правилом?
Имеет ли это смысл?
1 ответ:
Во-первых, вы должны быть ясны относительно условий замены, ваши правила говорят "не в начале слова и не до/после гласной", но вы не реализовали это в регулярном выражении. Вы можете сделать это с помощью отрицательного Lookahead/Lookbehind. Например:
- заменить a, i, o на u (если не в начале слова и если не перед / после гласной)
Можно реализовать с помощью:
Этот метод может быть использован для реализации первых 3 Правил.$patterns[] = "/(?<!\b|[aeiou])[aio](?![aeiou])/"; $replacements[] = "u";
В следующая проблема заключается в том, что "лиса" и "собака" будут затронуты первыми 3 правилами, поэтому вы должны заменить измененную версию на "волк" и "кошка". Итак, для собаки = > кошки:
$patterns[] = "/\bdug\b/"; $replacements[] = "cat";
Примечание: из-за того, как preg_replace работает с массивами, гораздо лучше не использовать индексы в массивах $patterns и $replacements, так как они могут вводить в заблуждение. Используйте оператор [] в парах, как я сделал выше, так что вы всегда знаете, что идет с чем.
Часть 2:
Ага. Я вижу. Вам нужно сделайте замену исключительной.
Можно использовать регулярное выражение, соответствующее обоим первым случаям, которые являются проблемными. Затем вы можете использовать интересную странную особенность preg_replace: когда вы добавляете модификатор
e
, строка замены вместо этого оценивается как PHP-код. Комбинируя это с группами захвата, вы сможете решить, выводить лиu
илиi
в соответствии с тем, что вы сопоставили.$patterns[] = "/(?<!\b|[aeiou])([aeiou])(?![aeiou])/e"; $replacements[] = '("$1" == "e" || "$1" == "u")? "i":"u"';
*Обратите внимание на /e и () вокруг класса соответствия гласных.