помогите составить regexp

vinslave

Новичок
помогите составить regexp

Например, имеется следующая строка

$s = 'ksjdfhksjdh ####(Hotel)### hsfghsdjfhgsjdf skjd k ksjh ksjdhf kjdf sdkjfhg ###(Hotel)### sdf sdfgsdfg hot dsfksgl dnfsgkdjfn kjn xcvbhotdfgdfg'

мне нужно найти вхождения "ote" в эту строку и заменить их на "###(ote)###",
но при одном условии: если "ote" уже находится между "###(" и ")###", как например "###(Hotel)###", то замену производить НЕ нужно.

Мне нужен универсальный regexp, который бы работал для общего случая, если в строке скажем есть "###(Bauerland)###" и нужно найти и заменить вхождения "land"
 

vinslave

Новичок
пробовал. ничего путного не вышло. к чему был твой вопрос?
 

WP

^_^
Figoro
Что-то ты какой из непонятливый =)
vinslave
PHP:
$s = 'ksjdfhksjdh ####(Hotel)### hsfghsdjfhgsjdf skjd k ksjh ksjdhf kjdf sdkjfhg ###(Hotel)### sdf sdfgsdfg hot dsfksgl dnfsgkdjfn kjn xcvbhotdfgdfg ote';
function callback($m)
{
 if (isset($m[1])) {return '###('.$m[1].')###';}
 return $m[0];
}
$find = 'ote';
echo preg_replace_callback('~###\(\w+\)###|('.preg_quote($find,'~').')~','callback',$s);
// ksjdfhksjdh ####(Hotel)### hsfghsdjfhgsjdf skjd k ksjh ksjdhf kjdf sdkjfhg ###(Hotel)### sdf sdfgsdfg hot dsfksgl dnfsgkdjfn kjn xcvbhotdfgdfg ###(ote)###
Публикую потому что автору потребовалось имхо слишком много переть чтоб допереть.
 

Anarki

Новичок
WP
Можно тогда и карманты использовать в простом preg_replace?
 

vinslave

Новичок
Автор оригинала: WP
Figoro

Публикую потому что автору потребовалось имхо слишком много переть чтоб допереть.
Хитрый жук. Спасибо тебе. Выручил. Я даже не знал про функцию preg_replace_callback, и что с её помощью можно так все выкрутить. respect!
 

boombick

boombick.org
вот вам и универсальный совет на все случаи жизни - читайте ман!!! :)
 

WP

^_^
boombick
В мане этого нет ;)
Anarki
Нет. Т.е. можно конечно юзать с модификатором 'e', но эти те же яйца только сбоку и через жопу =)

Уже писал кстати этот в оффтопике, тема про замену только тех слов которые не в кавычках. Суть данного кода вот в чем. Давайте представим поведение анализатора при обработке данной регулярки: ~<\w+>|(test)~ на тексте скажем: 1 <test> 2 test 3, сначала поиск ищется первый литерал - < или test (альтернатива), затем проверяется подходит ли t под \w и т.д. до >, затем наступает конец регулярки и данные передаются в callback, после возврата из функции значения $m[0] (самой строки без изменений) поиск идет уже дальше, и никакая регулярка не будет повторно воздействовать на текст возвращенный из callback. Можно и посложнее взять пример:
~((['"]).*?(?<!\\)\2|\w*\s*\(((?:(?R)|.)*?)\)|[\$#]\w+#?(?:\[(?:(?R)|((?:[^\]'"]*(?:(['"]).*?
(?<!\\)\5)?)*))*?\]|\.[\$#]?\w+#?|->\s*[\$#]?\w+(?:\(((?:(?R)|.)*?)\))?)*|-?\d+|
(?<=^|[\s\)\:\.=+\-<>])(?:\w+)(?=$|[\s\|\.\:\(=+\-<>]))(\s+(?:is(?:\s+not)?\s+
(?:eek:dd|div|even)\s+by\s+-?\d+|is(?:\s+not)?\s+(?:eek:dd|even)))?((?:\|@?\w+
(?:\:(?:\w*\(((?:(?R)|.)*?)\)|[\$#]\w+#?(?:\[(?:(?R)|((?:[^\]'"]*(?:(['"]).*?
(?<!\\)\11)?)*))*?\]|\.[\$#]?\w+#?)*|[^'"\:]*(?:[^'"\:]*(['"]).*?(?<!\\)\12[^'"\:]*)*))*)*)
|((?<=\s|\))(?:is\s+not|is|not\s+eq|eq|neq?|gt|lt|gt?e|ge|lt?e|mod)(?=\s|\()|(?:not\s+))~si
Вот такой одной preg_replace_callback парсю строчные выражения вложенные, вызовы функций и все остальное (в шаблоинзаторе). Регулярки могут больше чем вы думаете) Так что, господа, изучайте - пригодится.
vinslave
Еще изящнее в callback'е вызывать ту же регулярку рекурсивно :)

-~{}~ 08.05.07 14:35:

Рекурсивную регулярку рекурсивно вызывать в callback'е :-D
 
Сверху