Regex для замены строки в HTML, но не внутри ссылки или заголовка - PullRequest
3 голосов
/ 10 июня 2010

Я ищу регулярное выражение для замены заданной строки на html-странице, но только если строка не является частью самого тега или отображается в виде текста внутри ссылки или заголовка.

Примеры:

Ищем 'replace_me'

<p>You can replace_me just fine</p> ОК

<a href='replace_me'>replace_me</a> нет совпадений

<h3>replace_me</h3> нет совпадений

<a href='/test/'><span>replace_me</span></a> нет совпадений

<p style="background:url('replace_me')">replace_me<h1>replace_me</h1></p> первый не соответствует, второй в порядке, третий не соответствует

Заранее спасибо!

UPDATE:

Я нашел работающее регулярное выражение

\b(replace_me)\b(?!(?:(?!<\/?[ha].*?>).)*<\/[ha].*?>)(?![^<>]*>)

Ответы [ 3 ]

0 голосов
/ 10 июня 2010
\b(replace_me)\b(?!(?:(?!<\/?[ha].*?>).)*<\/[ha].*?>)(?![^<>]*>)
0 голосов
/ 06 сентября 2017

У меня была похожая проблема - учитывая строку HTML, я хотел заменить все экземпляры строки tio2 на TiO<sub>2</sub> и ticl4 на TiCl<sub>4</sub>.

Это было легко сделать с помощью простой замены строк, но были некоторые случаи, когда в доменных именах встречались «игольные» строки, например, www.ilovetio2.com, www.tastytastyticl4.info. В этих случаях атрибуты href будут нарушены заменой строки.

Вместо того, чтобы возиться с попыткой найти одно сложное регулярное выражение, я решил сделать два прохода над строкой HTML:

  • Заменить ВСЕ экземпляры на str_ireplace
  • Найдите атрибуты href, содержащие <sub>...</sub>, и исправьте их preg_replace_callback

    public static function subscriptStrings($str)
    {
    
        // $str is arbitrary string which may be HTML, may be plain text
    
        // Define search / replacements
        $map = [
            'tio2' => 'TiO<sub>2</sub>',
            'ticl4' => 'TiCl<sub>4</sub>'
        ];
    
        // Replace ALL instances, paying no heed to their context
        $str = str_ireplace(array_keys($map), array_values($map), $str);
    
        // Make a second pass, specifically looking for href values
        $str = preg_replace_callback('/href="[^"]+"/', function ($str) {
    
            // Return the href value stripped of <sub> tags
            return str_replace(['<sub>', '</sub>'], '', $str[0]);
        }, $str);
    
        return $str;
    }
    

Это не является пуленепробиваемым и потерпит неудачу, если по каким-то причинам рассматриваемые ссылки должны содержать в них по некоторым причинам.

0 голосов
/ 10 июня 2010

Синтаксический анализ HTML с помощью регулярных выражений - плохая идея, которая сведет вас с ума.Использование регулярных выражений для этого, вероятно, не так уж и плохо, но есть несколько вещей, о которых следует подумать при любом подходе:

  1. Сколько из них есть на странице?
  2. Какна скольких страницах вы будете это делать?
  3. Будете ли вы вручную проверять вывод или он автоматизирован?
  4. Какой язык (языки) вы используете для этого?

Я думаю, что лучший способ не с «простым» (читай: ужасно сложным) регулярным выражением, а с правильной программой, в которой есть некоторая логика - если регулярные выражения не являются полными по Тьюрингу и кто-то другой не может предоставить регулярное выражениеделать, что хочешь, конечно:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...