Замена слова на ссылку с учетом существующих ссылок и тегов

Разработка Зотиков Сергей 3 комментария

Требуется заменить некое слово в тексте на ссылку, например:

Как сообщал Интерфакс

на:

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

  1. tvolf

    У вас, похоже, неверный комментарий в функции. В самом начале написано:

    PHP
    // Нечетные элементы массива $split будут
    // содержать текс, а четные html теги

    А на самом деле текст будут содержать четные элементы массива (индексы 0, 2, 4 и т.д.), а в нечетных элементах массива $split будут лежать теги.
    В самой функции же все отрабатывает правильно, то есть, теги ищутся в нечетных элементах, то есть. неверный только комментарий.

    1. Сергей Зотиков

      Радует когда код не просто копируют, а вникают в него! Спасибо, ошибку исправил.

Поддерживаются `код`, **жирный**, *курсив* и блоки кода

Как оформить
ПишетеПолучится
`npm install`код в строке: npm install
```bash
npm install
npm run build
```
блок кода: три обратные кавычки — отдельной строкой до и после кода; язык подсветки (bash, php, sql) — по желанию, сразу после первых кавычек
**важно**важно
*термин*термин
https://example.comссылка: адрес достаточно вставить как есть
Наверх