Игнорировать определенный тег в регулярном выражении — отрицательный взгляд

Итак, у меня есть этот сценарий в моем php код, где у меня есть следующая строка

This is an outside Example <p href="https://example.com"> This is a para Example</p><markup class="m"> this is a markup example</markup>

И я хочу сделать поиск слова без учета регистра example в этой строке, но

  • Я хочу, чтобы мое регулярное выражение игнорировало появление примера внутри атрибута тега (чего я могу достичь)
  • Я хочу игнорировать поиск внутри следующего <markup ..> any content </markup> полностью

То, что я сделал до сих пор,

/(example)(?:[^<]*>)/i

Это прекрасно работает и игнорирует пример в href из p тег,
Теперь я изменил его для <markup>

/(example)(?!([^<]*>)|(\<markup[^>]*>[^<]*<\/markup\>))/i

но это не работает
ты можешь видеть мою работу — https://regex101.com/r/e2XujN/1

Чего я хочу добиться с этим

Я буду заменять подобранный example словом, следующим образом

  • Предположим, если я нашел eXamPle это будет заменено <markup>eXamPle</markup>
  • Example будет заменен на <markup>Example</markup>

и так далее,

Примечание: регистр шаблона в совпадающей строке и строке замены совпадает

2

Решение

Ты можешь использовать (*SKIP)(*F) основанный на PCRE для соответствия и пропуска определенных подстрок, заключенных в шаблон / строку (здесь наценка) как это:

(markup).*\1(*SKIP)(*F)|(example)(?![^<]*>)

Объяснение:

Исключенная подстрока: 1-я группа захвата
(разметка): буквально соответствует разметке символов (без учета регистра)
.* соответствует любому символу (кроме ограничителей строки)
\1 соответствует тому же тексту, что и первая группа захвата
(*SKIP) над
(*F) сокращение (* FAIL), не совпадает

1

Другие решения

Вы можете решить это так же, как и с первой проблемой. Проверьте, не сопровождается ли непосредственно за строкой закрывающий тег.

Regex:

(example)(?![^<]*>)(?![^<]*<\/markup\>)

демонстрация

1

Ответ — использование DOM, однако немного сложно работать с текстовыми узлами и вставлять в них HTML-контент.

PHP live демо

$content = <<< 'HTML'
This is an outside Example <p href="https://example.com"> This is a para Example</p>
test <markup class="m"> this is a markup example</markup> another example <p>example</p>
HTML;

// Initialize a DOM object
$dom = new DOMDocument();
// Use an HTML element tag as our HTML container
// @hakre [https://stackoverflow.com/a/29499718/1020526]
@$dom->loadHTML("<div>$content</div>");

$wrapper = $dom->getElementsByTagName('div')->item(0);
// Remove wrapper
$wrapper = $wrapper->parentNode->removeChild($wrapper);
// Remove all nodes of $dom object
while ($dom->firstChild) {
$dom->removeChild($dom->firstChild);
}
// Append all $wrapper object nodes to $dom
while ($wrapper->firstChild) {
$dom->appendChild($wrapper->firstChild);
}

$dox = new DOMXPath($dom);
// Query all elements in addition to text nodes
$query = $dox->query('/* | /text()');

// Iterate through all nodes
foreach ($query as $node) {
// If it's not an HTML element
if ($node->nodeType != XML_ELEMENT_NODE) {
// Replace desired word / content
$newContent = preg_replace('~(example)~i',
'<markup>$1</markup>',
$node->wholeText);
// We can't insert HTML directly into our node
// so we need to create a document fragment
$newNode = $dom->createDocumentFragment();
$newNode->appendXML($newContent);
// Replace new content with old one
$node->parentNode->replaceChild($newNode, $node);
}
}

// Save modifications
echo $dom->saveHTML($dom);
0
По вопросам рекламы [email protected]