Php 如何匹配重复并包含任何内容(包括新行)的短代码之类的内容

Php 如何匹配重复并包含任何内容(包括新行)的短代码之类的内容,php,regex,preg-replace-callback,non-greedy,Php,Regex,Preg Replace Callback,Non Greedy,我试图通过preg_replace_回调函数处理类似于shrotcode的内容: $new_content = preg_replace_callback("|\[BLOCK\s?(TYPE=[0-9a-z\/]+)?\s?(TEXT=[a-z]+)?\s?(LAST)?\s?\]((?:(?!BLOCK).)*)\[\/BLOCK\]|","block",$content); 例如,主题$content如下所示: [BLOCK TYPE=1/2 TEXT=right LAST] <ul

我试图通过preg_replace_回调函数处理类似于shrotcode的内容:

$new_content = preg_replace_callback("|\[BLOCK\s?(TYPE=[0-9a-z\/]+)?\s?(TEXT=[a-z]+)?\s?(LAST)?\s?\]((?:(?!BLOCK).)*)\[\/BLOCK\]|","block",$content);
例如,主题$content如下所示:

[BLOCK TYPE=1/2 TEXT=right LAST]
<ul><li>something</li>
</ul>
[/BLOCK]
[BLOCK TYPE=1/2 TEXT=right LAST][NEXTSHORTCODE=something][/BLOCK]
[BLOCK TYPE=1/2 TEXT=right LAST]123[/BLOCK]
我遇到了一个问题:

函数preg_replace_callback将整个主题从一个块匹配到最后一个/BLOCK,而不是第一次出现/BLOCK。 我想解决它,不包括字符串块?:?!BLOCK.*来自短代码的内部内容,但不适用于其他字符,如换行符等

您可以在此处看到我的尝试:


感谢您的建议,并为糟糕的英语感到抱歉。

您需要使用所谓的惰性匹配表达式作为结束标记

您的正则表达式以\[\/BLOCK\]结尾


是否尝试以\[\/BLOCK\]结尾?相反这将使它与它发现的第一个延迟而不是最后一个贪婪匹配。

再加上Ollie所说的,如果你不关心块内的类型和其他引用,只想替换所有块,你可以使用以下简单的方法:

$regex = "~(?s)\[BLOCK.*?/BLOCK]~";
$new_content = preg_replace_callback($regex, $block, $subject);
function block($m) {
  // replace magic
  return $something;
}
您缺少m开关

试试这个:

\[BLOCK\s?TYPE=[0-9a-z\/]+?\s?TEXT=[a-z]+?\s?LAST?\s?\]?:?!块。*\[\/BLOCK\]

演示