假设我们有一个名为test的标签,即[code]
。
我想做的是,我想在字符串中的每个主[code]
标记内只允许最多X个其他[code]
标记,这意味着最内部的标记会被删除。
因此,例如,如果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]元素,所以它不会太乱。
我想知道如何实现这一点,只是试着想一个算法,并希望得到任何建议。
答案 0 :(得分: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.
答案 1 :(得分: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]
*/
答案 2 :(得分:0)
我不知道你在这里会发生什么,但如果你把它作为HTML输出,你可以将这个规则添加到你的样式表中:
test test test test test { display: none; }
显然,它必须是一个真实的元素,因为<test>
不是html的一部分。