2

假设我们有一个名为 test 的标签,即[code].

我想做的是,我只想在字符串[code]中的每个主[code]标签内最多允许 X 个其他标签,这意味着最内部的标签将被删除。

因此,例如,如果 X = 4,则以下字符串:

[code]a[code]b[code]c[code]d[code]e[code]f[code]g[/code][/code][/code][/code][/code][/code][/code]

会成为:

[code]a[code]b[code]c[code]d[code]e[/code][/code][/code][/code][/code]

以及以下字符串:

[code]a[code]b[code]c[code]d[code]TEST[/code][code]e[code]f[code]g[/code][/code][/code][/code][/code][/code][/code]

会成为:

[code]a[code]b[code]c[code]d[code]TEST[/code][code]e[/code][/code][/code][/code][/code]

这里的目标是在一个代码元素中不要有多个嵌套的 [code] 元素,这样它就不会变得太乱。

我想知道如何实现这一点,只是想一个算法,并希望得到任何建议。

4

3 回答 3

1

看起来您可以使用 JBBCode:

http://jbbcode.com/docs#definingNewCodes

addBBCode's fifth and last parameter is a nest limit. By default 
the nest limit is -1, meaning no limit. Nest limits allow you to 
define a bbcode such that if the bbcode is embedded multiple times, 
elements nested beyond the nest limit will be omitted from the output. 
于 2012-05-29T20:32:04.607 回答
1

这将是相当浪费的,因为在这里添加多个标签支持等非常容易。无论哪种方式,您几乎都必须完全进行树解析。

请注意,无效输入不会以任何方式处理,标签必须适当平衡

function get_node_contents( $node ) {
    $orig = $node;
    $ret = "[code]" . $node->content;

    if( @$node->children ) {
        foreach( $node->children as $node ) {
            $ret .= get_node_contents( $node );
        }
    }


    if( @$orig->endContent ) {
        $ret .= $orig->endContent;
    }
    return $ret."[/code]";

}

function reduce_depth( $str, $maxDepth = 4 ) {
    $index = 0;
    $len = strlen( $str );
    $reg = '/(\[code\]|\[\/code\])/';

    $root = new stdClass;
    $root->children = array();
    $depth = 0;
    $ret = "";

    $pos = strpos( $str, "[code]" );

    if( $pos ) {
        $ret .= substr( $str, 0, $pos - 0);
    }

    while( $index < $len  ) {

        if( !preg_match( $reg, $str, $matches, PREG_OFFSET_CAPTURE, $index )) {
            break;
        }

        $index = ( $matches[1][1] + strlen( $matches[1][0] ) );
        $tag = $matches[1][0];

        $next = preg_match( $reg, $str, $matches, PREG_OFFSET_CAPTURE, $index );
        $content = "";

        if( $next ) {
            $content = substr( $str, $index, $matches[1][1] - $index );
        }

        if( $tag === "[code]" ) {
            if( $depth === 0 ) {
                $parent = $root->children[] = new stdClass;
                $parent->content = $content;
                $depth++;
            }
            else if ( $depth++ > $maxDepth ) {

                continue;
            }
            else {
                if( !@$parent->children ) {
                    $parent->children = array();
                }
                $child = $parent->children[] = new stdClass;
                $child->content = $content;
                $child->parent = $parent;
                $parent = $child;
            }        
        }
        else {                
            $depth--;

            if( @$parent->parent ) {
                $parent = $parent->parent;
            }

            if( @$content ) {
                $parent->endContent = $content;
            }                

        }

    }


    foreach( $root->children as $node ) {
        $ret .= get_node_contents( $node );
    }

    $ret .= substr( $str, $index, $len - $index );


    return $ret;

}

echo reduce_depth( "asdasdas[code]l[/code][code]a[code]lol[/code][code]b[code]c[code]d[code]e[code]f[code]g[/code][/code][/code][/code][/code][/code][/code]aasdasdsasd", 4 ). "\n";
echo reduce_depth( "[code]a[code]b[code]c[code]d[code]e[code]f[code]g[/code][/code][/code][/code][/code][/code][/code]", 4 ) . "\n";
echo reduce_depth( "[code]a[code]b[code]c[code]d[code]TEST[/code][code]e[code]f[code]g[/code][/code][/code][/code][/code][/code][/code]", 4 ) . "\n";
echo reduce_depth("[code][code]bugi[/code]bugi2[/code]", 1) . "\n"; 
echo reduce_depth("[code][code]bugi[/code]bugi2[code]bugi3[/code]bugi4[code]bugi5[/code]bugi6[/code]", 3) . "\n"; 


/*
    asdasdas[code]l[/code][code]a[code]lol[/code][code]b[code]c[code]d[code]e[/code][/code][/code][/code][/code]aasdasdsasd
    [code]a[code]b[code]c[code]d[code]e[/code][/code][/code][/code][/code]
    [code]a[code]b[code]c[code]d[code]TEST[/code][code]e[/code][/code][/code][/code][/code]
    [code][code]bugi[/code]bugi2[/code]
    [code][code]bugi[/code][code]bugi3[/code][code]bugi5[/code]bugi6[/code]

*/
于 2012-05-29T21:52:58.237 回答
0

我不知道你在这里做什么,但如果你将它输出为 HTML,你可以将这个规则添加到你的样式表中:

test test test test test { display: none; }

显然,它必须是一个真实的元素,因为<test>它不是 html 的一部分。

于 2012-05-29T20:25:03.617 回答