我花了很长时间来处理这个问题,并希望通过补充尊敬的ZyX的答案来完全关闭这个问题。
他提供了一个非常好的搜索模板,但正如Moe所说,嵌套引用本身并不是这样处理的。
为了解决这个问题,我使用了一个while循环和ZyX的模式,以及preg_replace_callback函数:
$text =
'
[QUOTE=ctmcn]
[quote="John Doe;1000"]Lorem ipsum dolor sit amet[/quote]
Lorem ipsum dolor sit amet
[/QUOTE]
-----------------------------
[QUOTE="John Doe;103318"]
[QUOTE]
[QUOTE="John-Doe;103318"]
Lorem ipsum dolor sit amet
[/QUOTE]
Lorem ipsum dolor sit amet
[/QUOTE]
Lorem ipsum dolor sit amet
[QUOTE="John-Doe;103318"]
Lorem ipsum dolor sit amet
[/QUOTE]
Lorem ipsum dolor sit amet
[QUOTE="John-Doe;103318"]
Lorem ipsum dolor sit amet
[/QUOTE]
Lorem ipsum dolor sit amet
[/QUOTE]
Lorem ipsum dolor sit amet
----------------------------
[QUOTE="John-Doe;103318"]Lorem ipsum dolor sit amet[/QUOTE]
----------------------------
[QUOTE="Максим;103318"]Lorem ipsum dolor sit amet[/QUOTE]
Lorem ipsum dolor sit amet
'
$text = nestedQuotes($text);
function nestedQuotes($text) {
while (preg_match('#\[quote=?(.*?)\](((?R)|.)*?)\[\/quote\]#is', $text)) {
$text = preg_replace_callback (
'#\[quote=?(.*?)\](((?R)|.)*?)\[\/quote\]#is',
function($m) {
if ($m[1]) {
if (strpos(';', $m[1])) {
list($qname, $qpostid) = str_replace('"', '', explode(";", $m[1]));
if ($qname && !$qpostid) return 'here code with quotet username and without source post_id, LIKE: [qoute="username";]text[/quote]';
if ($qname && $qpostid) return 'here code with quotet username and with source post_id, LIKE: [qoute="username;postid"]text[/quote]';
} else {
$qname = str_replace('"', '', $m[1]);
return 'here code with quotet username and without source post_id [qoute=username]text[/quote]';
}
} else {
return 'here anonymous quote, LIKE: [quote]text/quote]';
}
},
$text
);
echo $text;
}
}
像这样,您可以打败任何级别的嵌套和任何类型的引号。
preg_replace_callback函数允许使用函数作为替换参数,借助它,我们可以根据原始引用的形式找出要返回哪个响应(是否可能获取被引用用户的名称、被引用消息的ID等)。
变量$m是带有捕获组的数组。
$m[0] its all captured pattern.
$m[1] its first captured group
$m[2] its second captured group...
等等等等...
但是这种方法有一个缺点。搜索模板非常“贪婪”,在大量文本上我遇到了php工作中的问题。它不返回任何值,也不报告任何错误。
如果有人添加更优化的搜索模板,那将是完美的解决方案。
希望这能帮助到某些人!