Итак, у меня есть этот сценарий в моем 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>
и так далее,
Примечание: регистр шаблона в совпадающей строке и строке замены совпадает
Ты можешь использовать (*SKIP)(*F)
основанный на PCRE для соответствия и пропуска определенных подстрок, заключенных в шаблон / строку (здесь наценка) как это:
(markup).*\1(*SKIP)(*F)|(example)(?![^<]*>)
Объяснение:
Исключенная подстрока: 1-я группа захвата
(разметка): буквально соответствует разметке символов (без учета регистра)
.*
соответствует любому символу (кроме ограничителей строки)
\1
соответствует тому же тексту, что и первая группа захвата
(*SKIP)
над
(*F)
сокращение (* FAIL), не совпадает
Вы можете решить это так же, как и с первой проблемой. Проверьте, не сопровождается ли непосредственно за строкой закрывающий тег.
Regex:
(example)(?![^<]*>)(?![^<]*<\/markup\>)
Ответ — использование DOM, однако немного сложно работать с текстовыми узлами и вставлять в них HTML-контент.
$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);