PHP preg заменяет несколько правил


Мне просто интересно, как применить несколько правил для preg_replace, не выполняя их при первом запуске. Это немного сложно, позвольте мне объяснить на примере.

Ввод:

$string = 'The quick brown fox jumps over the lazy freaky dog'; 

Правила:

  • Заменить a, я, o с u (если не в начале слова и если не до/после гласной)
  • Заменить e, u с i (если не в начале слова и если нет перед/после гласной)
  • Заменить ea на i (если не в начале слова)
  • Замените целые слова, т.е. собака на кошка и лиса на волк (без применения правил выше)

Вывод: Этот быстрый волк-брюнет прыгает над этим лузи-фрики-котом




Я начал с чего-то вроде этого: ( Отредактировано благодаря Иезекиилю Мансу)

$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



Отредактированный:

Как вы можете видеть, проблема в том, что каждое правило перезаписывается предыдущим правилом.

Пример 'лиса':

  1. правило: превращает фокса в факса
  2. правило: превращает fux в исправление

Есть ли способ избежать следующего правила(правил), если на персонажа уже повлияло предыдущее правило?

Имеет ли это смысл?

Author: T.Rob, 2010-08-10

1 answers

Сначала вам нужно четко указать условия замены, в ваших правилах говорится "не в начале слова и не до/после гласной", но вы не реализовали это в регулярном выражении. Вы можете сделать это, используя Отрицательный взгляд/Взгляд сзади. Например:

  1. Замените a, i, o на u (если не в начале слова и если не до/после гласной)

Может быть реализован с помощью:

$patterns[] = "/(?<!\b|[aeiou])[aio](?![aeiou])/";
$replacements[] = "u";

Этот метод может быть использован для реализации первых 3 правила.

Следующая проблема заключается в том, что на "лису" и "собаку" будут влиять первые 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 и () вокруг гласной соответствующий класс.

 3
Author: Ezequiel Muns, 2010-08-11 08:33:50