Регулярное выражение - поиск ключевых слов в тексте и создание из них ссылок

Кинотавр

Новичок
Регулярное выражение - поиск ключевых слов в тексте и создание из них ссылок

Всех приветствую.

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

К примеру, есть массив слов "губы", "губам", "губ". Я этот массив превращаю в элемент регулярного выражения, представленного ниже.

PHP:
<? 
$s = "<H1>Весь этот блеск</H1><P>Некоторые ошибочно полагают, что мужчина, прежде всего, обращает внимание на глаза! По статистике, первое, на что он смотрит на нашем лице – это Губы. Мы в редакции протестировали блеск L’Oreal Глам Шайн 6 Часов, который призван сделать губы привлекательными, объемными и сияющими.</P><P>Инновационная технология, разработанная лабораториями L’OREAL – использование единственно возможной формулы, которая дает возможность создать пленкообразующий полимер, который противостоит прикосновениям (большая стойкость, даже во время еды) и который, в то же время, обладает очень мягкой текстурой (еще больший комфорт ваших губ).</P><P><STRONG>Наши выводы:</STRONG> если подставить лицо к весеннему солнцу, то губы, накрашенные блеском Глам Шайн, выглядят как будто с картинки. Дополнительный объем виден сразу после нанесения. Кстати, о нанесении, у блеска необычный аппликатор, который очень легко скользит по губам, специально для аккуратистов. Но что подкупило нас окончательно: блеск держится очень долго. Он держится после еды, после питья – точное время не засекали, но все в один голос твердили, что долго, а это для блесков редкость.</P><P><STRONG>Результат:</STRONG> действительно сияющее, мягкое и стойкое покрытие, глянцевая, равномерная поверхность губ и гарантированно долгая стойкость.</P><P>Губернский вестник</P>"; 

echo (preg_replace("/[^0-9a-zA-Zа-яА-ЯЁё](губы|губам|губ)[^0-9a-zA-Zа-яА-ЯЁё]/i","<a href=\"#\">\\0</a>",$s));  
?>
Здесь у меня оформляются в виде ссылок все те вхождения, которые не являются частью других слов. То есть, в слове "Губернский" ничего ссылкой не становится.

Но возникла такая проблема. В ссылку попадают предыдущий и последующий символы нужного нам вхождения. То есть, пробел или запятая. А надо, чтобы ссылкой становилось только ключевое слово.

Прошу помочь.
Спасибо.
 

Кинотавр

Новичок
Благодарю.

Получилось следующее, вроде работает.
Проверьте, пожалуйста, все ли учтено.

PHP:
echo (preg_replace("/\b(губы|губам|губ)\b/i","<a href=\"#\">\\0</a>",$s));
 

Кинотавр

Новичок
Гм, возникла проблема.
Если в тексте уже есть ссылка, и искомое слово попадает в нее, то получается коллизия.
Чего делать-то, мужики? Как исключить из поиска ключевых слов содержимое тега <a>...</a>?
И, кстати, еще надо исключить ситуацию, когда текст содержится внутри alt и title.

-~{}~ 12.09.08 01:44:

Никто не захотел помочь, выходит?
 

dimagolov

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

п.с. а скулить "Никто не захотел помочь" не стоит, большинство тех, кто в России-Европе уже просто спит, не спит Америка.
 

Кинотавр

Новичок
Насчет "скулить" - попрошу повежливее. Коли ты тут санитар, то и веди себя прилично, выбирай выражения.
Сообщение было написано 9 сентября, а мой "скулеж" начался 12-го. Между 9-м и 12-м люди два раза просыпались и снова засыпали по всему миру. Будь внимательнее. ;)

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

Gas

может по одной?
заменять каким-то одинаковым кодом
ответ простой, заменять не одинаковым кодом, смотри в регах на модификатор e или замену с callback'ом.
 

Кинотавр

Новичок
Gas, благодарю! Очень мне помог.

В результате вот какой код получился.


Сперва снова вкратце постановка задачи с привнесенными коррективами.

Имеется текст, в котором надо определенные слова оформить в виде ссылок. Текст находится в переменной $content, слова - переменная $s, в которой слова разделены символом "|". Необходимо обрамить тегами <a>...</a> все вхождения ключевых слов, не застрагивая при этом уэе имеющиеся ссылки <a>...</a>, картинки <img> и заголовки <h1>...</h1>, <h2>...</h2> и т. д.

PHP:
$content = '<h1>Весь этот блеск</h1><p><img src="pic.jpg" alt="Блеск и красота губ" align="right">Некоторые ошибочно полагают, что мужчина, прежде всего, обращает внимание на глаза! По статистике, первое, на что он смотрит на нашем лице – <a href="#" title="Блеск и красота">это губы</a>. Мы в редакции протестировали блеск L’Oreal Глам Шайн 6 Часов, который призван сделать губы привлекательными, объемными и сияющими.</p>";

$s = "губ|губы|губам|блеск|блеску";

              
// Выборка всех тегов <a> в массив $a_array
unset($a_array);
preg_match_all("'<a[^>]*?>.*?</a>'si",$content,$a_array);

// Замена всех тегов <a> заглушкой [a_array]
$content = preg_replace("'<a[^>]*?>.*?</a>'si",'[a_array]',$content);


// Выборка всех тегов заголовков в массив $h_array
unset($h_array);
preg_match_all("'<h[1-9][^>]*?>.*?</h[1-9]>'si",$content,$h_array);

// Замена всех тегов заголовков заглушкой [h_array]
$content = preg_replace("'<h[1-9][^>]*?>.*?</h[1-9]>'si",'[h_array]',$content);


// Выборка всех тегов <img> в массив $img_array
unset($img_array);
preg_match_all('/(<img[^>]*?>)/si',$content,$img_array);

// Замена всех тегов <img> заглушкой [img_array]
$content = preg_replace('/(<img[^>]*?>)/si','[img_array]',$content);


// Замена всех вхождений ключевых слов ссылками
$content = preg_replace('/\b('.$s.')\b/i','<a href="#">\\1</a>',$content);


// Возвращаем теги <a> на свои места
$i = 0;
$content = preg_replace('~\[a_array\]~e', '$a_array[0][$i++];', $content);


// Возвращаем теги заголовков на свои места
$i = 0;
$content = preg_replace('~\[h_array\]~e', '$h_array[0][$i++];', $content);


// Возвращаем теги <img> на свои места
$i = 0;
$content = preg_replace('~\[img_array\]~e', '$img_array[0][$i++];', $content);


echo ($content);
 
Сверху