Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Тексты > эвуляция кода в preg_replace(модификатор e)


Автор: skyboy 15.3.2007, 15:55
есть код:
Код

echo preg_replace('#(<code>)(.*)(</code>)#e','$2','<code>"2"."3"</code>');

выдает ошибку:
Цитата

Warning: Unexpected character in input: '\' (ASCII=92) state=1 in .....: regexp code on line 1
Parse error: syntax error, unexpected $end in ...: regexp code on line 1
Fatal error: preg_replace() [<a href='function.preg-replace'>function.preg-replace</a>]: Failed evaluating code: \'2\'.\'3\' in ....

По-видимому, я просто не понимаю, как работает выполнение кода в preg_replace. 
Ведь код 
Код

eval(preg_replace('#(<code>)(.*)(</code>)#','$2;','<code>echo "2"."3"</code>'));

срабатывает.
а код
Код

echo preg_replace('#(<code>)(.*)(</code>)#','$2','<code>"2"."3"</code>');

выводит
Цитата

"2"."3"

Откель рога растут? Что я неверно понимаю?

Добавлено @ 16:03 
Цитата(skyboy @  15.3.2007,  14:55 Найти цитируемый пост)
Unexpected character in input: '\'

учитывая, что символа "\" не было в начальной строке 
Цитата

<code>"2"."3"</code>

подумал было нехорошее на magic_quotes. Механизм оказался включенным. Но после отключения ничего не изменилось - та же ругань на те же ошибки в тех же местах.
 smile 

Автор: Bikutoru 15.3.2007, 16:22
Похоже, кавычки в найденном фрагменте текста предварительно экранируются. По крайней мере такой вариант
Код

print preg_replace(
    '#(<code>)(.*)(</code>)#e',
    '"$2"',
    '<code>"2" . "3"</code>'
);

отрабатывает просто отлично. Правда, смысл модификатора e  здесь не ясен. 
Сам этот модификатор нужен для того, чтобы как-то обработать полученные результаты. Например так:
Код

print preg_replace(
    '/{char=(\d+)}/e',
    'chr($1)',
    '{char=72}{char=101}{char=108}{char=108}{char=111}'
);


Добавлено @ 16:26 
См. также http://ru.php.net/manual/ru/function.preg-replace.php#39713

Автор: mishaSL 15.3.2007, 16:27
skyboy, проблема в том, что в строке поиска используются кавычки.
модификатор /e - заставляет PHP интерпритировать второй параметр функции preg_replace как PHP код. Вообще этот модификатор работает только с функцией preg_replace. Но по своей природе он очень не совершенен, т.к. он выполняет код после подстановки значений, из-за этого возникают проблемы.
Советую для этих целей использовать функцию preg_replace_callback()  smile  

Автор: skyboy 15.3.2007, 16:32
Цитата(Bikutoru @  15.3.2007,  15:22 Найти цитируемый пост)
Похоже, кавычки в найденном фрагменте текста предварительно экранируются.

похоже. но magic_quotes отключен, а вставить strip_slashes можно только, если интерпретатор не будет валиться ещё до выполнения strip_slashes. а он, зараза, валится :(
в принципе, можно сначала просто заменить, потом убрать экранирование, а потом "вручную" вызвать eval. 
но хочется понять, что я не так понял в работе preg_replace smile
Цитата(Bikutoru @  15.3.2007,  15:22 Найти цитируемый пост)
Правда, смысл модификатора e  здесь не ясен.

а смысл мне приводить немаленький кусок(чтоб всё было и можно было выполнить скрипт без "додумывания" недостающего) кода, в котором использование "е" оправдано, коль даже в таком маленьком куске ошибка воспроизводится?  smile 
конечно, пример немного надуман smile 

Автор: skyboy 15.3.2007, 16:50
Цитата(mishaSL @  15.3.2007,  15:27 Найти цитируемый пост)
Советую для этих целей использовать функцию preg_replace_callback() 

да я понимаю smile
у меня есть обходные пути. просто не понимаю, почему такая ерунда :(
Цитата(mishaSL @  15.3.2007,  15:27 Найти цитируемый пост)
модификатор /e - заставляет PHP интерпритировать второй параметр функции preg_replace как PHP код.

а
Цитата

echo "2"."3"

невалидный РНР код? smile если добавить в конце ";" - он же очень хорошо выполняет в eval.
Цитата(Bikutoru @  15.3.2007,  15:22 Найти цитируемый пост)
См. также http://ru.php.net/manual/ru/function.preg-replace.php#39713 

спасибо(а ведь читал коменты! :(). в таком случае можно обойти извратом(только сейчас пришло в голову, когда выяснилось, что добавление слешей к кавычкам - нормальная практика для preg_replace) 
Код

echo preg_replace('#(<code>)(.*)(</code>)#e','eval(strip_slashes("$2"))','<code>"2"."3"</code>');

Автор: mishaSL 15.3.2007, 16:59
Цитата(skyboy @  15.3.2007,  16:32 Найти цитируемый пост)
но magic_quotes отключен


Не имеет значение включен magic_quotes или нет. При использовании модификатора /e автоматически применяется функция - addslashes()

Автор: skyboy 15.3.2007, 17:18
Цитата(mishaSL @  15.3.2007,  15:59 Найти цитируемый пост)
При использовании модификатора /e автоматически применяется функция - addslashes()

но в доку ментации этого нет :(
только в комментарии к документации, за ссылку на который спасибо Bikutoru.
А magic_quotes просто была одним из вариантов. smile Я вот не люблю, когда люди спрашивают, и ожидают, что за них кто-то все проблемы решит. А сами сидят и ждут smile Вот и пробовал разные возможные причины.

Добавлено @ 17:25 
Цитата

echo preg_replace('#(<code>)(.*)(</code>)#e','eval(strip_slashes("$2"))','<code>"2"."3"</code>');

ну, почти так. ведь в данном случае eval не вернет результат и выводить будет нечего. я про сам подход.
да уж. лучше preg_reaplce_callback

Автор: mishaSL 15.3.2007, 18:33
Цитата(skyboy @  15.3.2007,  17:18 Найти цитируемый пост)
А magic_quotes просто была одним из вариантов. smile Я вот не люблю, когда люди спрашивают, и ожидают, что за них кто-то все проблемы решит. А сами сидят и ждут smile Вот и пробовал разные возможные причины.


Это правильно smile  А про magic_quotes я сказал для общей информации.




Цитата(skyboy @  15.3.2007,  17:18 Найти цитируемый пост)
да уж. лучше preg_reaplce_callback 


Это точно smile 

Автор: skyboy 15.3.2007, 18:57
спасибо тому, кто пометил вопрос решенным smile Я как-то руками промахал

Добавлено @ 18:58 
Bikutoru, mishaSL, ребят, спасибо за помощь.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)