在PHP中删除嵌套的bbcode(引号) [英] Removing nested bbcode (quotes) in PHP

查看:78
本文介绍了在PHP中删除嵌套的bbcode(引号)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从公告板上删除嵌套引用,但是我遇到了一些问题.

I'm trying to remove nested quoting from my bulletin board, but I'm having some issues.

示例输入:

[quote author = personX link = topic = 12.msg1910#msg1910 date = 1282745641]

[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]

[quote author=PersonZ link=topic=1.msg1#msg1 date=1282533805]

随机三引号

[/quote]

示例输出

[quote author = personX link = topic = 12.msg1910#msg1910 date = 1282745641]

[quote author=personX link=topic=12.msg1910#msg1910 date=1282745641]

第二个引号中的消息

[/quote]

[quote author = PersonZ link = topic = 1.msg1#msg1 date = 1282533805]

[quote author=PersonZ link=topic=1.msg1#msg1 date=1282533805]

随机三引号

[/quote]

如您所见,嵌套的引号(原始消息)以及引号标签已被删除.

As you can see the nested quote (The original message) is removed, along with the quote tags.

我似乎无法弄清楚.

当我尝试

$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); 

它什么也没做.

对此有何想法?

感谢您的帮助,Haggi.

Thanks for your help, Haggi.

虽然我仍然遇到麻烦.

while循环

while ( $input = preg_replace_callback( '~\[quoute.*?\[/quote\]~i', 'replace_callback', $input ) ) {
// replace every occurence
}

使页面无限循环,如果将其删除(以及多余的u),页面将无法执行任何操作.

causes the page to loop indefinitely, when removed (along with the extra u in quoute), the page doesn't do anything.

我确定原因是匹配的

更改为

$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.

此外,undo_replace函数存在问题,因为它永远找不到存储的哈希,它仅给出有关未找到索引的警告.我猜匹配sha1的正则表达式无法正常工作.

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 :)

推荐答案

很容易发现第一个是唯一留下的:

that the first one is the only one that stays is quite easily found out:

'$found++ ? \'\' : \'$1\''

开始时,$ found是未定义的,其结果为false,因此返回$ 1.然后$ found递增为1(undefined + 1 = 1),因此它大于零,并且每次调用它时,它都会进一步递增.因为所有与零不同的东西在之后都会被评估为真,所以您总是会得到".

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.

您想要做的就是这样

$cache = array();

function replace_callback( $matches ) {
    global $cache;
    $hash = sha1sum( $matches[0] );
    $cache[$hash] = $matches[0];
    return "REPLACE:$hash";
}

// replace all quotes with placeholders
$count = 0;
do {
    $input = preg_replace_callback( '~\[quoute.*?\[/quote\]~i', 'replace_callback', $input, -1, $count );
    // replace every occurence
} while ($count > 0);

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 );

此代码未经测试,因为我没有手头的PHP对其进行测试.如果您无法解决任何错误,请在此处发布,我会予以解决.

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

这篇关于在PHP中删除嵌套的bbcode(引号)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆