Помогите с preg_replace #2

V3
На сайте с 08.09.2015
Offline
54
809

Привет. Имеется регулярное выражение, которое игнорирует при замене <h2>слово</h2>

$text = preg_replace('/(?<!\p{L}|<h2>)'.preg_quote($value['faq_menu'], '/').'(?!\p{L}|<\/h2>)/ui', '<a href="/faq/'.$value['faq_url'].'/">\0</a>', $text);

Необходимо игнорировать <h2>лала слово блабла</h2>, мне посоветовали

$text = preg_replace('/\G(?:<h2>.*?<\/h2>|\K(?<!\p{L})'.preg_quote($value['faq_menu'], '/').'(?!\p{L})(*ACCEPT)|.)++(?!)/uis', '<a href="/faq/'.$value['faq_url'].'/">\0</a>', $text);

но оно не работает. Подскажет кто-то где ошибка или как правильно сделать?

J
На сайте с 20.02.2014
Offline
120
jkm
#1

На первый взгляд всё работает http://sandbox.onlinephpfunctions.com/code/35b8eac340c696d9dbccf358d095e72bea47dbd4

Нужен пример текста, где не работает.

Еще хотелось бы узнать какая там версия библиотеки для работы с регулярными выражениями и какая версия PHP.


echo "PHP ", PHP_VERSION, ", PCRE ", PCRE_VERSION, "\n";

Сразу после preg_replace можно добавить вызов preg_last_error() и посмотреть номер ошибки.


var_dump( preg_last_error() );

Если текст большой возможно превышение лимитов pcre.backtrack_limit или pcre.recursion_limit.

---------- Добавлено 29.10.2016 в 10:16 ----------

Вот ещё вариант


$text = preg_replace("/<h2.*?<\/h2>(*SKIP)(?!)|(?<!\p{L})\Q{$value['faq_menu']}\E(?!\p{L})/uis", '<a href="/faq/'.$value['faq_url'].'/">\0</a>', $text);
S
На сайте с 30.09.2016
Offline
469
#2
jkm:
какая версия PHP

Кстати, по Вашей ссылке код не работает под PHP с версией ниже 5.3.10. Может быть, ТС следует упростить шаблон, исключив из него навороты типа \G ? Ведь работали как-то с регулярками до выхода новых версий PHP.

Отпилю лишнее, прикручу нужное, выправлю кривое. Вытравлю вредителей.
V3
На сайте с 08.09.2015
Offline
54
#3
jkm:
На первый взгляд всё работает http://sandbox.onlinephpfunctions.com/code/35b8eac340c696d9dbccf358d095e72bea47dbd4
Нужен пример текста, где не работает.
Еще хотелось бы узнать какая там версия библиотеки для работы с регулярными выражениями и какая версия PHP.

echo "PHP ", PHP_VERSION, ", PCRE ", PCRE_VERSION, "\n";


Сразу после preg_replace можно добавить вызов preg_last_error() и посмотреть номер ошибки.

var_dump( preg_last_error() );


Если текст большой возможно превышение лимитов pcre.backtrack_limit или pcre.recursion_limit.

---------- Добавлено 29.10.2016 в 10:16 ----------

Вот ещё вариант

$text = preg_replace("/<h2.*?<\/h2>(*SKIP)(?!)|(?<!\p{L})\Q{$value['faq_menu']}\E(?!\p{L})/uis", '<a href="/faq/'.$value['faq_url'].'/">\0</a>', $text);

PHP 5.2.6, PCRE 7.6 2008-01-28 видимо, дело в старой версии, никаких ошибок не выводится. Второй вариант вроде работает, спасибо.

V3
На сайте с 08.09.2015
Offline
54
#4

Всплыла новая проблема с этим вариантом

$text = preg_replace("/<h2.*?<\/h2>(*SKIP)(?!)|(?<!\p{L})\Q{$value['faq_menu']}\E(?!\p{L})/uis", '<a href="/faq/'.$value['faq_url'].'/">\0</a>', $text);

Если $value['faq_menu'] = 'слово', то всё работает нормально и блабласловоблабла остаётся без ссылки.

Если $value['faq_menu'] = 'Т-15'; то Т-150 превращается в <a href>Т-15</a>0.

Как избежать появления ссылок в таком случае?

S
На сайте с 30.09.2016
Offline
469
#5

Будь проще и люди потянутся к тебе (С)

$text = preg_replace("/<h2.*?<\/h2>(*SKIP)(?!)|(?<= )\Q{$value['faq_menu']}\E(?= )/uis", '<a href="/faq/'.$value['faq_url'].'/">\0</a>', $text);
V3
На сайте с 08.09.2015
Offline
54
#6

Спасибо, и ещё один вопрос, забыл сразу написать в посте. Возможна ситуация, когда после искомого слова стоит точка или запятая. В таком случае реплейс не срабатывает. Как исправить?

S
На сайте с 30.09.2016
Offline
469
#7
$text = preg_replace("/<h2.*?<\/h2>(*SKIP)(?!)|(?<= )\Q{$value['faq_menu']}\E[.;]?(?= )/uis", '<a href="/faq/'.$value['faq_url'].'/">\0</a>', $text);

Здесь срабатывает, если стоит одна точка, одна точка с запятой, или ничего не стоит.

А вот так - чтобы знак препинания не входил в ссылку:

$text = preg_replace("/<h2.*?<\/h2>(*SKIP)(?!)|(?<= )\Q{$value['faq_menu']}\E(?=[.;]? )/uis", '<a href="/faq/'.$value['faq_url'].'/">\0</a>', $text);

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий