阻止PHP preg_replace替换shortcode标记中的文本



在WordPress中,我们可以使用以下格式在帖子内容中使用短代码功能:

[shortcode]数据[/shortcode]

例如:

[shortcode]Lorem ipsum[/shortcode]多洛尔·西特·阿梅elit。发酵实践lacinia。Ut猥亵purus interdum砂眼唇。

我的问题是,我们需要什么正则表达式来替换帖子内容中的任何文本,除了短代码中的文本?

问题没有说明要替换什么文本以及用什么替换。考虑使用此代码来搜索/替换shortcode标记之外的某些模式。

目标:斜体显示foo的每次出现,但不在shortcode标记内。

$str = "foo
 bar[shortcode]foo[/shortcode]foo 123
 bar [shortcode]foo[/shortcode] foo"; // post content
$query = "foo"; // search pattern
$query = preg_quote($query, '~');
$p = '~(([shortcode])(?(2).*?[/shortcode])(?:.*?))*?(' . $query . ')~smi';
$s = preg_replace($p, "$1<i>$3</i>", $str);
var_dump($s);

输出

String(100) "<i>foo</i>
 bar[shortcode]foo[/shortcode]<i>foo</i> 123
 bar [shortcode]foo[/shortcode] <i>foo</i>"

如您所见,上面的输出将搜索文本foo封装到shortcode标记外的斜体文本ONLY中。

s/.*[shortcode]([^[]*)[/shortcode].*/1/gm

以下正则表达式将匹配shortcode标记之间的所有内容,而不匹配其他内容:

  • (?<=[shortcode]).*?(?=[/shortcode])

它查找[shortcode]之后的位置,然后匹配[/shortcode]之前结束的任何字符串(尽可能短)。

如果你想在PHP中打印所有这些中间字符串,你需要这样的代码:

preg_match_all('%(?<=[shortcode]).*?(?=[/shortcode])%s',
                               $input, $result, PREG_PATTERN_ORDER);
for ($i = 0; $i < count($result[0]); $i++) {
    echo $result[0][$i];
}

如果要在循环外使用捕获的文本,请将echo $result[0][$i];行替换为:

  • $output .= $result[0][$i];

最新更新