Выражение PHP Regex, исключая & lt; pre & gt; тег

Я использую плагин WordPress с именем Сокращения (https://wordpress.org/plugins/acronyms/). Этот плагин заменяет сокращения их описанием. Он использует PHP preg_replace функция.

Проблема в том, что он заменяет аббревиатуры, содержащиеся в <pre> тег, который я использую для представления исходного кода.

Не могли бы вы изменить это выражение, чтобы оно не заменяло аббревиатуры, содержащиеся внутри <pre> теги (не только напрямую, но и в любой момент)? Является ли это возможным?

Код PHP:

$text = preg_replace(
"|(?!<[^<>]*?)(?<![?.&])\b$acronym\b(?!:)(?![^<>]*?>)|msU", "<acronym title=\"$fulltext\">$acronym</acronym>", $text
);

2

Решение

Вы можете использовать PCRE SKIP / FAIL регулярное выражение трюк (также работает в PHP), чтобы заставить механизм регулярных выражений сопоставлять что-либо, только если оно не находится внутри некоторых разделителей:

(?s)<pre[^<]*>.*?<\/pre>(*SKIP)(*F)|\b$acronym\b

Это означает: пропустить все подстроки, начинающиеся с <pre> и заканчивая </pre>и только потом совпадать $acronym как целое слово.

Увидеть демо на regex101.com

Вот пример PHP демо:

<?php
$acronym = "ASCII";
$fulltext = "American Standard Code for Information Interchange";
$re = "/(?s)<pre[^<]*>.*?<\\/pre>(*SKIP)(*F)|\\b$acronym\\b/";
$str = "<pre>ASCII\nSometext\nMoretext</pre>More text \nASCII\nMore text<pre>More\nlines\nASCII\nlines</pre>";
$subst = "<acronym title=\"$fulltext\">$acronym</acronym>";
$result = preg_replace($re, $subst, $str);
echo $result;

Выход:

<pre>ASCII</pre><acronym title="American Standard Code for Information Interchange">ASCII</acronym><pre>ASCII</pre>
3

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

Также возможно использовать preg_split и сохраните блок кода как группу, замените только часть, не являющуюся блоком кода, затем объедините ее обратно в виде полной строки:

function replace($s) {
return str_replace('"', '&quot;', $s); // do something with `$s`
}

$text = 'Your text goes here...';
$parts = preg_split('#(<\/?[-:\w]+(?:\s[^<>]+?)?>)#', $text, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
$text = "";
$x = 0;
foreach ($parts as $v) {
if (trim($v) === "") {
$text .= $v;
continue;
}
if ($v[0] === '<' && substr($v, -1) === '>') {
if (preg_match('#^<(\/)?(?:code|pre)(?:\s[^<>]+?)?>$#', $v, $m)) {
$x = isset($m[1]) && $m[1] === '/' ? 0 : 1;
}
$text .= $v; // this is a HTML tag…
} else {
$text .= !$x ? replace($v) : $v; // process or skip…
}
}

return $text;

Взято из Вот.

0

По вопросам рекламы [email protected]