2010-08-09 2 views
2

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

Вход:

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

Правила:

  • Replace , я, о с у (если не в начале слова & если не befor е/после гласного)
  • Заменить е, ˙U с я (если не в начале слова & если не до/после гласного)
  • Заменить е с я (если не в начале слова)
  • Заменить целые слова, т.е. собаки с кошки и лисом с ш олф (без применения вышеуказанных правил)

Выход: Thi быстро bruwn волк jimps над Тхи Luzy friky кошка




Я начал с чем-то вроде этого: (Отредактированные благодаря 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 



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

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

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

  1. правило: превращает лиса в Фукс
  2. правило: превращает FUX в затруднительного

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

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

+0

Откуда взялся «freaky»? Пфф. Я хочу, чтобы регулярное выражение создавало правильную фразу: P – 2010-08-10 00:00:52

ответ

3

Прежде всего вам нужно четко указать условия замены, ваши правила говорят «не в начале слова, а не до/после гласного», но вы не реализовали это в регулярном выражении. Вы можете сделать это, используя Negative Lookahead/Lookbehind. Например:

  1. заменить, I, O с и (если не в начале слова & если не до/после гласного)

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

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

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

Следующая проблема заключается в том, что «лисица» и «собака» будут затронуты первыми тремя правилами, поэтому вы должны заменить версию на «волк» и «кот». Так что для собаки => кошка:

$patterns[] = "/\bdug\b/"; 
$replacements[] = "cat"; 

Примечание: Из-за особенностей preg_replace работает с массивами, это гораздо лучше, чтобы не использовать индексы в $ шаблонов и $ заменители массивов, так как они могут вводить в заблуждение. Используйте оператор [] в парах, как я сделал выше, поэтому вы всегда знаете, что с ним связано.

Часть 2:

Aha. Понимаю. Вам нужно сделать замену эксклюзивной.

Вы можете использовать регулярное выражение, которое соответствует как первым случаям, которые являются проблематичными. Затем вы можете использовать интересную странную особенность preg_replace: когда вы добавляете модификатор e, вместо этого вместо этого заменяется строка PHP. Объединяя это с группами захвата, он позволит вам решить, выводить ли u или i в соответствии с тем, что вы соответствовали.

$patterns[] = "/(?<!\b|[aeiou])([aeiou])(?![aeiou])/e"; 
$replacements[] = '("$1" == "e" || "$1" == "u")? "i":"u"'; 

* Обратите внимание на/e и() вокруг класса соответствия гласных.

+0

Спасибо, чувак, который работает как шарм. :) Но, пожалуйста, см. Мой отредактированный пост выше. – Mayko

+0

Ой, и еще одна вещь, вам нужно убедиться, что вы также используете lookbehind в своем '/ ea /', потому что вы сказали * не в начале слова *. –

+0

Удивительно! огромное спасибо – Mayko