Замена слова на ссылку с учетом существующих ссылок и тегов
Требуется заменить некое слово в тексте на ссылку, например:
Как сообщал Интерфакс
на:
HTML
Как сообщал <a href="http://www.interfax.ru">Интерфакс</a>
Вроде все просто реализуется на PHP с помощью регулярного выражения:
PHP
<?php
$text = 'Как сообщал Интерфакс';
$word = 'интерфакс';
$text = preg_replace('/(' . $word . ')/iu', '<a href="/news.html">$0</a>', $text);
Но этот скрипт не учитывает, что слово уже может быть ссылкой или находиться в атрибуте html-тега и его не надо заменять на ссылку. Поэтому для замены слов на ссылки требуется более сложная конструкция:
PHP
<?php
$text = 'Любой текст с html или без него <a href="/">содержащий</a> <span data-text="слово">cлово</span>';
$word = 'Слово';
// Нечетные элементы массива $split будут
// содержать html теги, а четные текс
$split = preg_split('/(<.*?>)/s', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
// По умолчанию замена слов на ссылки разрешена
$flag = true;
for ($i = 0; $i < count($split); $i++) {
if ($i & 1) {
// Если обнаружен открывающий тег a, то замена слов на ссылку запрещается
if (preg_match('/(<a.*?>)/i', $split[$i])) {
$flag = false;
}
// Если обнаружен закрывающий тег a, то замена слов на ссылку разрешается
if (preg_match('/(<\/a>)/i', $split[$i])) {
$flag = true;
}
} elseif ($flag) {
$split[$i] = preg_replace('/(' . $word . ')/iu', '<a href="/news.html">$0</a>', $split[$i]);
}
}
$text = implode('', $split);
echo $text;
Комментарии 3
Спасибо за полезный пост!
У вас, похоже, неверный комментарий в функции. В самом начале написано:
// Нечетные элементы массива $split будут // содержать текс, а четные html тегиА на самом деле текст будут содержать четные элементы массива (индексы 0, 2, 4 и т.д.), а в нечетных элементах массива $split будут лежать теги.
В самой функции же все отрабатывает правильно, то есть, теги ищутся в нечетных элементах, то есть. неверный только комментарий.
Радует когда код не просто копируют, а вникают в него! Спасибо, ошибку исправил.
Написать комментарий