preg_replace только теги OUTSIDE? (… мы не говорим о полном «анализе html», просто немного уценке)

Каков самый простой способ применения подсветки текста, исключающего текст в тегах OCCASIONAL «<…>»?

РАЗРЕШЕНИЕ : Я хочу, чтобы существующие теги СОХРАНЯЕМСЯ!

$t = preg_replace( "/(markdown)/", "<strong>$1</strong>", "This is essentially plain text apart from a few html tags generated with some simplified markdown rules: <a href=markdown.html>[see here]</a>"); 

Который должен отображаться как:

«Это по существу простой текст, кроме нескольких HTML-тегов, созданных с помощью некоторых упрощенных правил уценки : см. Здесь "

… НО НЕ СООБЩАЙТЕ текст внутри тега привязки (т.е. <a href=markdown.html> ).

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

На самом деле, похоже, это работает нормально:

 <?php $item="markdown"; $t="This is essentially plain text apart from a few html tags generated with some simplified markdown rules: <a href=markdown.html>[see here]</a>"; //_____1. apply emphasis_____ $t = preg_replace("|($item)|","<strong>$1</strong>",$t); // "This is essentially plain text apart from a few html tags generated // with some simplified <strong>markdown</strong> rules: <a href= // <strong>markdown</strong>.html>[see here]</a>" //_____2. remove emphasis if WITHIN opening and closing tag____ $t = preg_replace("|(<[^>]+?)(<strong>($item)</strong>)([^<]+?>)|","$1$3$4",$t); // this preserves the text before ($1), after ($4) // and inside <strong>..</strong> ($2), but without the tags ($3) // "This is essentially plain text apart from a few html tags generated // with some simplified <strong>markdown</strong> rules: <a href=markdown.html> // [see here]</a>" ?> 

Строка типа $item="odd|string" вызовет некоторые проблемы, но я все равно не буду использовать такую ​​строку … (возможно, нужны htmlentities (…) или тому подобное …)

Вы можете разделить строку на тег / без тегов с помощью preg_split :

 $parts = preg_split('/(<(?:[^"\'>]|"[^"<]*"|\'[^\'<]*\')*>)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE); 

Затем вы можете выполнять итерацию частей, пропуская каждую четную часть (т. Е. Части тега ) и применять на ней свою замену:

 for ($i=0, $n=count($parts); $i<$n; $i+=2) { $parts[$i] = preg_replace("/(markdown)/", "<strong>$1</strong>", $parts[$i]); } 

В конце все складывается вместе с implode :

 $str = implode('', $parts); 

Но обратите внимание, что это действительно не лучшее решение. Лучше использовать правильный HTML-парсер, как библиотека DOM PHP. См. Например, эти связанные вопросы:

  • Выделите ключевые слова в абзаце
  • Regex / DOMDocument – сопоставление и замена текста не в ссылке

Вы можете разделить строку на массив на каждом «<» или «>», используя preg_split() , затем прокрутите этот массив и замените только на записи, не начинающиеся с «>». После этого вы объединяете массив в строку с помощью метода implode() .

Это регулярное выражение должно удалить все открывающие и закрывающие теги HTML: /(<[.*?]>)+/

Вы можете использовать его с preg_replace следующим образом:

 $test = "Hello <strong>World!</strong>"; $regex = "/(<.*?>)+/"; $result = preg_replace($regex,"",$test); 

на самом деле это не очень эффективно, но это сработало для меня

 $your_string = '...'; $search = 'markdown'; $left = '<strong>'; $right = '</strong>'; $left_Q = preg_quote($left, '#'); $right_Q = preg_quote($right, '#'); $search_Q = preg_quote($search, '#'); while(preg_match('#(>|^)[^<]*(?<!'.$left_Q.')'.$search_Q.'(?!'.$right_Q.')[^>]*(<|$)#isU', $your_string)) $your_string = preg_replace('#(^[^<]*|>[^<]*)(?<!'.$left_Q.')('.$search_Q.')(?!'.$right_Q.')([^>]*<|[^>]*$)#isU', '${1}'.$left.'${2}'.$right.'${3}', $your_string); echo $your_string; в $your_string = '...'; $search = 'markdown'; $left = '<strong>'; $right = '</strong>'; $left_Q = preg_quote($left, '#'); $right_Q = preg_quote($right, '#'); $search_Q = preg_quote($search, '#'); while(preg_match('#(>|^)[^<]*(?<!'.$left_Q.')'.$search_Q.'(?!'.$right_Q.')[^>]*(<|$)#isU', $your_string)) $your_string = preg_replace('#(^[^<]*|>[^<]*)(?<!'.$left_Q.')('.$search_Q.')(?!'.$right_Q.')([^>]*<|[^>]*$)#isU', '${1}'.$left.'${2}'.$right.'${3}', $your_string); echo $your_string;