Я пытаюсь сделать регулярное выражение для соответствия и замены появления ключевого слова на части HTML:
keyword
и <strong>keyword</strong>
<a href="someurl.html" target="_blank">keyword</a>
и <a href="someur2.html">already linked keyword </a>
НЕ должны быть сопоставлены Меня интересует только сопоставление (и замена) keyword
на первой строке.
Причина, по которой я хочу это, – заменить keyword
<a href="dictionary.php?k=keyword">keyword</s>
, но ТОЛЬКО, если keyword
уже не находится в теге <a>
.
Любая помощь будет высоко ценится!
$str = preg_replace('~Moses(?!(?>[^<]*(?:<(?!/?a\b)[^<]*)*)</a>)~i', '<a href="novo-mega-link.php">$0</a>', $str);
Выражение внутри негативного внешнего вида соответствует следующему закрывающему тегу </a>
, но только если он не видит первый тег <a>
. Если это удастся, это означает, что слово Moses
находится внутри элемента привязки, поэтому просмотр не выполняется, и совпадение не происходит.
Вот демо .
Мне удалось сделать то, что я хотел ( без использования Regex ):
<a>
(копирование их во временный массив и сохранение заполнителя в строке) str_replace
новая строка, чтобы заменить все ключевые слова <a>
Вот код, который я использовал, в случае, если кому-то это понадобится:
$str = <<<STRA Moses supposes his toeses are roses, but <a href="original-moses1.html">Moses</a> supposes erroneously; for nobody's toeses are posies of roses, as Moses supposes his toeses to be. Ganda <span class="cenas"><a href="original-moses2.html" target="_blank">Moses</a></span>! STRA; $arr1 = str_split($str); $arr_links = array(); $phrase_holder = ''; $current_a = 0; $goto_arr_links = false; $close_a = false; foreach($arr1 as $k => $v) { if ($close_a == true) { if ($v == '>') { $close_a = false; } continue; } if ($goto_arr_links == true) { $arr_links[$current_a] .= $v; } if ($v == '<' && $arr1[$k+1] == 'a') { /* <a */ // keep collecting every char until </a> $arr_links[$current_a] .= $v; $goto_arr_links = true; } elseif ($v == '<' && $arr1[$k+1] == '/' && $arr1[$k+2] == 'a' && $arr1[$k+3] == '>' ) { /* </a> */ $arr_links[$current_a] .= "/a>"; $goto_arr_links = false; $close_a = true; $phrase_holder .= "{%$current_a%}"; /* put a parameter holder on the phrase */ $current_a++; } elseif ($goto_arr_links == false) { $phrase_holder .= $v; } } echo "Links Array:\n"; print_r($arr_links); echo "\n\n\nPhrase Holder:\n"; echo $phrase_holder; echo "\n\n\n(pre) Final Phrase (with my keyword replaced):\n"; $final_phrase = str_replace("Moses", "<a href=\"novo-mega-link.php\">Moses</a>", $phrase_holder); echo $final_phrase; echo "\n\n\nFinal Phrase:\n"; foreach($arr_links as $k => $v) { $final_phrase = str_replace("{%$k%}", $v, $final_phrase); } echo $final_phrase;
Выход:
Массив ссылок:
Array ( [0] => <a href="original-moses1.html">Moses</a> [1] => <a href="original-moses2.html" target="_blank">Moses</a> )
Фразовый держатель:
Moses supposes his toeses are roses, but {%0%} supposes erroneously; for nobody's toeses are posies of roses, as Moses supposes his toeses to be. Ganda <span class="cenas">{%1%}</span>!
(pre) Окончательная фраза (с замененным ключевым словом):
<a href="novo-mega-link.php">Moses</a> supposes his toeses are roses, but {%0%} supposes erroneously; for nobody's toeses are posies of roses, as <a href="novo-mega-link.php">Moses</a> supposes his toeses to be. Ganda <span class="cenas">{%1%}</span>!
Финальная фраза:
<a href="novo-mega-link.php">Moses</a> supposes his toeses are roses, but <a href="original-moses1.html">Moses</a> supposes erroneously; for nobody's toeses are posies of roses, as <a href="novo-mega-link.php">Moses</a> supposes his toeses to be. Ganda <span class="cenas"><a href="original-moses2.html" target="_blank">Moses</a></span>!
$lines = explode( "\n", $content ); $lines[0] = stri_replace( "keyword", "replacement", $lines[0] ); $content = implode( "\n", $lines );
или если вы явно хотите использовать регулярное выражение
$lines = explode( "\n", $content ); $lines[0] = preg_replace( "/keyword/i", "replacement", $lines[0] ); $content = implode( "\n", $lines );
Подумайте об использовании библиотеки разбора HTML вместо обычного выражения, например simplehtmldom . Вы можете использовать его для обновления содержимого определенных тегов HTML (поэтому, игнорируя те, которые вы не хотите изменять). Тогда вам не придется использовать регулярное выражение; просто используйте функцию str_replace
после фильтрации соответствующих тегов.