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
Отредактированный:
Как вы можете видеть, проблема в том, что каждое правило перезаписывается предыдущим правилом.
Пример 'лиса':
- правило: превращает фокса в факса
- правило: превращает fux в исправление
Есть ли способ избежать следующего правила(правил), если на персонажа уже повлияло предыдущее правило?
Имеет ли это смысл?
1 answers
Сначала вам нужно четко указать условия замены, в ваших правилах говорится "не в начале слова и не до/после гласной", но вы не реализовали это в регулярном выражении. Вы можете сделать это, используя Отрицательный взгляд/Взгляд сзади. Например:
- Замените 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 и () вокруг гласной соответствующий класс.