删除 PHP 中嵌套的 bbcode(引号)
我正在尝试从公告板上删除嵌套引用,但遇到了一些问题。
输入示例:
[引用作者=personX链接=topic=12.msg1910#msg1910日期=1282745641]
[引用作者=PersonY link=topic=12.msg1795#msg1795 date=1282727068] 原始报价中的消息 [/引用]
第二条消息引用第一条消息
[/引用]
[引用作者=PersonZ link=topic=1.msg1#msg1 date=1282533805]
随机的第三个报价
[/引用]
输出示例
[引用作者=personX链接=topic=12.msg1910#msg1910日期=1282745641]
第二个报价中的消息
[/引用]
[引用作者=PersonZ link=topic=1.msg1#msg1 date=1282533805]
随机的第三个报价
[/引用]
正如您所看到的,嵌套的引用(原始消息)以及引用标签都被删除了。
我似乎无法弄清楚。
当我尝试时
$toRemove = '(\\[)(quote)(.*?)(\\])';
$string = $txt;
$found = 0; echo preg_replace("/($toRemove)/e", '$found++ ? \'\' : \'$1\'', $string);
,它会删除除第一个之外的所有引用标记,
但是当我将代码扩展为:
$toRemove = '(\\[)(quote)(.*?)(\\])(.*?)(\\[\\/quote\\])';
$string = $txt;
$found = 0; echo preg_replace("/($toRemove)/e", '$found++ ? \'\' : \'$1\'', $string);
它根本停止执行任何操作。
对此有什么想法吗?
编辑:
谢谢你的帮助,哈吉。
但我还是不断遇到麻烦。
while 循环
while ( $input = preg_replace_callback( '~\[quoute.*?\[/quote\]~i', 'replace_callback', $input ) ) {
// replace every occurence
}
会导致页面无限循环,当删除时(以及引号中的额外 u ),页面不会执行任何操作。
我确定原因是
更改为代码时
$input = preg_replace_callback( '/\[quote(.*?)/i', 'replace_callback', $input );
匹配确实开始工作,但更改为
$input = preg_replace_callback( '/\[quote(.*?)\[\/quote\]/i', 'replace_callback', $input );
它再次停止执行任何操作。
此外,undo_replace 函数也存在一个问题,因为它永远找不到存储的哈希值,它只给出有关未找到索引的警告。我猜匹配 sha1 的正则表达式无法正常工作。
我现在拥有的完整代码:
$cache = array();
$input = $txt;
function replace_callback( $matches ) {
global $cache;
$hash = sha1( $matches[0] );
$cache["hash"] = $matches[0];
return "REPLACE:$hash";
}
// replace all quotes with placeholders
$input = preg_replace_callback( '/\[quote(.*?)\[quote\]/i', 'replace_callback', $input );
function undo_replace( $matches ) {
global $cache;
return $cache[$matches[1]];
}
// restore the outer most quotes
$input = preg_replace_callback( '~REPLACE:[a-f0-9]{40}~i', 'undo_replace', $input );
// remove the references to the inner quotes
$input = preg_replace( '~REPLACE:[a-f0-9]{40}~i', '', $input );
echo $input;
再次感谢大家的任何想法:)
I'm trying to remove nested quoting from my bulletin board, but I'm having some issues.
Example input:
[quote author=personX link=topic=12.msg1910#msg1910 date=1282745641]
[quote author=PersonY link=topic=12.msg1795#msg1795 date=1282727068] The message in the original quote [/quote]
A second message quoting the first one
[/quote]
[quote author=PersonZ link=topic=1.msg1#msg1 date=1282533805]
A random third quote
[/quote]
Example output
[quote author=personX link=topic=12.msg1910#msg1910 date=1282745641]
Message in the second quote
[/quote]
[quote author=PersonZ link=topic=1.msg1#msg1 date=1282533805]
A random third quote
[/quote]
As you can see the nested quote (The original message) is removed, along with the quote tags.
I can't seem to figure it out.
When i try
$toRemove = '(\\[)(quote)(.*?)(\\])';
$string = $txt;
$found = 0; echo preg_replace("/($toRemove)/e", '$found++ ? \'\' : \'$1\'', $string);
It removes every occurrence of of the quote tag except the first one,
But when i expand the code to:
$toRemove = '(\\[)(quote)(.*?)(\\])(.*?)(\\[\\/quote\\])';
$string = $txt;
$found = 0; echo preg_replace("/($toRemove)/e", '$found++ ? \'\' : \'$1\'', $string);
It stops doing anything at all.
Any ideas on this ?
Edit:
Thanks for your help, Haggi.
Ik keep running in to trouble though.
The while loop around
while ( $input = preg_replace_callback( '~\[quoute.*?\[/quote\]~i', 'replace_callback', $input ) ) {
// replace every occurence
}
causes the page to loop indefinitely, when removed (along with the extra u in quoute), the page doesn't do anything.
I've determined that the cause is the matching
when changed to
$input = preg_replace_callback( '/\[quote(.*?)/i', 'replace_callback', $input );
the code does start working, but when changed to
$input = preg_replace_callback( '/\[quote(.*?)\[\/quote\]/i', 'replace_callback', $input );
It stopts doing anything again.
Also, there is an issue with the undo_replace function as it never finds the stored hash, it only gives warnings about unfound indexes. The regex matching the sha1 isn't working correctly i guess.
The complete code as I have it now:
$cache = array();
$input = $txt;
function replace_callback( $matches ) {
global $cache;
$hash = sha1( $matches[0] );
$cache["hash"] = $matches[0];
return "REPLACE:$hash";
}
// replace all quotes with placeholders
$input = preg_replace_callback( '/\[quote(.*?)\[quote\]/i', 'replace_callback', $input );
function undo_replace( $matches ) {
global $cache;
return $cache[$matches[1]];
}
// restore the outer most quotes
$input = preg_replace_callback( '~REPLACE:[a-f0-9]{40}~i', 'undo_replace', $input );
// remove the references to the inner quotes
$input = preg_replace( '~REPLACE:[a-f0-9]{40}~i', '', $input );
echo $input;
Thanks again for any ideas guys :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第一个是唯一留下的,很容易发现:
当启动时,$found 是未定义的,并且计算结果为 false,因此返回 $1。然后 $found 增加到 1 ( undefined + 1 = 1 ),因此它大于零,并且每次调用它时都会进一步增加。因为所有与零不同的东西都被评估为 true,之后您总是会得到 '' 返回。
你想要做的是这样的事情
这段代码未经测试,因为我手头没有 PHP 来测试它。如果有任何无法修复的错误,请将它们发布在这里,我会修复它们。
干杯,
哈吉
that the first one is the only one that stays is quite easily found out:
When starting $found is undefined and evaluates to false so the $1 is returned. Then $found gets incremented to 1 ( undefined + 1 = 1 ) so it is greater that zero and every time it gets called it's further incremented. As everything that is different from zero is evaluated as true after that you always get the '' back.
What you want to do is something like this
This code is untested as I don't habe PHP at hand to test it. If there are any errors you cannot fix, please just post them here and I will fix them.
Cheers,
haggi
我已经用 preg_replace 搜索了几种用于嵌套引号的解决方案,但没有人工作。所以我根据我的要求尝试了我的小版本。
希望这会对某人有所帮助。
I've searched for couple of solutions with preg_replace for nested quotes but no one worked. So i tried my littel version according to my requirement.
Hope this will help someone.