Каков самый простой способ применения подсветки текста, исключающего текст в тегах 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. См. Например, эти связанные вопросы:
Вы можете разделить строку на массив на каждом «<» или «>», используя 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;