Я работаю над этой функцией PHP. Идея состоит в том, чтобы обернуть некоторые слова, происходящие в строке, в определенные теги (как слова, так и теги, заданные в массиве). Он работает нормально !, но когда эти слова встречаются в связанном тексте или его атрибуте «src», тогда, конечно, ссылка разбивается и заполняется тегами, или теги, которые не должны быть внутри ссылки, генерируются. Это то, что у меня есть сейчас:
function replace() { $terminos = array ( "beneficios" => "h3", "valoracion" => "h2", "empresarios" => "h2", "tecnologias" => "h2", "...and so on..." => "etc", ); foreach ($terminos as $key => $value) { $body = "string where the word empresarios should be replaced; but the word <a href='http://www.empresarios.com'>empresarios</a> should not be replaced inside <a> tags nor in the URL of their 'src' attribute."; $tagged = "<".$value.">".$key."</".$value.">"; $result = str_replace($key, $tagged, $body); } }
Функция в этом примере должна возвращать "string where the word <h2>empresarios</h2> should be replaced; but the word <a href='http://www.empresarios.com'>empresarios</a> should not be replaced inside <a> tags nor in the URL of their 'src' attribute."
Я бы хотел, чтобы эта функция замены работала по всей строке, но не внутри тегов, ни по ее атрибутам!
(Я хотел бы сделать то, что упоминается в следующем потоке, это просто, что он не в javascript, что мне нужно, но в PHP: /questions/1666790/how-to-replace-text-not-within-a-specific-tag-in-javascript
)
Используйте DOM и только модифицируйте текстовые узлы:
$s = "foo <a href='http://test.com'>foo</a> lorem bar ipsum foo. <a>bar</a> not a test"; echo htmlentities($s) . '<hr>'; $d = new DOMDocument; $d->loadHTML($s); $x = new DOMXPath($d); $t = $x->evaluate("//text()"); $wrap = array( 'foo' => 'h1', 'bar' => 'h2' ); $preg_find = '/\b(' . implode('|', array_keys($wrap)) . ')\b/'; foreach($t as $textNode) { if( $textNode->parentNode->tagName == "a" ) { continue; } $sections = preg_split( $preg_find, $textNode->nodeValue, null, PREG_SPLIT_DELIM_CAPTURE); $parentNode = $textNode->parentNode; foreach($sections as $section) { if( !isset($wrap[$section]) ) { $parentNode->insertBefore( $d->createTextNode($section), $textNode ); continue; } $tagName = $wrap[$section]; $parentNode->insertBefore( $d->createElement( $tagName, $section ), $textNode ); } $parentNode->removeChild( $textNode ); } echo htmlentities($d->saveHTML());
Отредактировано для замены DOMText с DOMText и DOMElement по мере необходимости.
К ответу, который вы указали, в JS, это в основном то же самое. Вам просто нужно указать, что это строка.
$regexp = "/(<pre>(?:[^<](?!\/pre))*<\/pre>)|(\:\-\))/gi";
Также обратите внимание, что вам может понадобиться другая функция preg_replace, чтобы заменить слово empresarios на случай, если оно заглавное (Empresarios) или как странное (EmPreSAriOS).
Также позаботьтесь о своем HTML. <h2>
являются блочными элементами и могут быть интерпретированы следующим образом:
строка, в которой следует заменить слово empresarios;
И заменили
строка, в которой слово
Empresarios
следует заменить;
Возможно, вам понадобится тег <big>
.