更新时间:2023-10-25 22:09:52
您可以使用 PCRE SKIP/FAIL regex 技巧(也适用于 PHP)告诉正则表达式引擎只匹配不在某些分隔符内的内容:
(?s).*?(*SKIP)(*F)|\b$acronym\b
这意味着:跳过所有以
开头并以
结尾的子串,然后才匹配$acronym
作为一个整体.
这是一个示例 PHP 演示:
.*?(*SKIP)(*F)|\\b$acronym\\b/";$str = "<pre>ASCII\nSometext\nMoretext</pre>更多文本\nASCII\n更多文本<pre>More\nlines\nASCII\nlines</pre>";$subst = "<acronym title=\"$fulltext\">$acronym</acronym>";$result = preg_replace($re, $subst, $str);回声 $result;
输出:
<pre>ASCII</pre><acronym title="美国信息交换标准代码">ASCII</acronym><pre>ASCII</pre>
I am using a WordPress plugin named Acronyms (https://wordpress.org/plugins/acronyms/). This plugin replaces acronyms with their description. It uses a PHP PREG_REPLACE function.
The issue is that it replaces the acronyms contained in a <pre>
tag, which I use to present a source code.
Could you modify this expression so that it won't replace acronyms contained inside <pre>
tags (not only directly, but in any moment)? Is it possible?
The PHP code is:
$text = preg_replace(
"|(?!<[^<>]*?)(?<![?.&])\b$acronym\b(?!:)(?![^<>]*?>)|msU"
, "<acronym title=\"$fulltext\">$acronym</acronym>"
, $text
);
You can use a PCRE SKIP/FAIL regex trick (also works in PHP) to tell the regex engine to only match something if it is not inside some delimiters:
(?s)<pre[^<]*>.*?<\/pre>(*SKIP)(*F)|\b$acronym\b
This means: skip all substrings starting with <pre>
and ending with </pre>
, and only then match $acronym
as a whole word.
Here is a sample PHP demo:
<?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;
Output:
<pre>ASCII</pre><acronym title="American Standard Code for Information Interchange">ASCII</acronym><pre>ASCII</pre>