我正在从一些旧的论坛软件升级,其中包含许多不必要的嵌套[QUOTE]标签,我想通过Regex(使用PHP preg_replace)删除它。其中大部分已经完成,但我正在努力使用以下类型。
帖子中有嵌套的引用块,但只需保留顶级[QUOTE]内容(因为一些嵌套引号的深度为3或4级)。
例如:
Here is some normal post content
[QUOTE]
This is an appropriate quote
[/QUOTE]
Here is more post content
[QUOTE]
This is a a valid quote, as it's only 1 level deep.
[QUOTE="User 2"]
Here's an unnecessary nested quote.
[QUOTE]
Here's a 3nd level unnecessary nested quote.
[/QUOTE]
[/QUOTE]
[/QUOTE]
Here is more post content
我想删除第二级和第三级嵌套引号,但无法弄清楚如何。
我完全对strip nested quotes提出了一些很好的建议,但我无法修改正则表达式以适合这个例子。
答案 0 :(得分:2)
与您链接的正则表达式相同的限制(引号内没有其他标记),您可以使用
((?:\[QUOTE\]|\G(?!^))[^][]+)((\[QUOTE[^][]*\](?:[^][]++|(?2))++\[/QUOTE\]))
搜索,然后$1
仅替换嵌套引号。
这基本上匹配单独组中的最外层引用,并且仅匹配递归中的内部引号,因此只允许删除它们。
请参阅https://regex101.com/r/y39Xaf/2
我在外引号中添加了一个带有两个不同引号的测试用例。
((?:\[QUOTE\]|\G(?!^))[^][]+)
上的细分:
(?:\[QUOTE\]|\G(?!^)
匹配文字[QUOTE]
或上一场比赛的结尾[^][]+
匹配任何普通文字答案 1 :(得分:1)
是的,您可以使用链接答案中的相同正则表达式并将 两次 与一些编程逻辑结合使用:
<?php
$regex = '~
(\[QUOTE[^][]*\]
(?:[^][]++|(?1))++
\[/QUOTE\])
~x';
$data = preg_replace_callback($regex,
function($match) use($regex) {
return $match[0][0] . preg_replace($regex, '', substr($match[0], 1));
},
$your_data_string_here);
echo $data;
?>
<小时/> 这样可以得到您的示例:
Here is some normal post content
[QUOTE]
This is an appropriate quote
[/QUOTE]
Here is more post content
[QUOTE]
This is a a valid quote, as it's only 1 level deep.
[/QUOTE]
Here is more post content
<小时/> 这里的想法是匹配每个引用标记(嵌套或不嵌套),然后将相同的表达式应用于匹配的字符串,但偏移量为+1。当我们获取子字符串时,只找到下一个嵌套的
[QUOTE]
集,然后替换它。
demo on regex101.com和on ideone.com进一步澄清了这一点。