src/thinkextend/parser/driver/Ubb.php
private function closeTag($data, $rule = '')
    {
        static $tag, $reg, $func, $count = 0;
        if (is_string($data)) {
            list($tag, $reg[0], $reg[1], $func) = $rule;
            do {
                $data = preg_replace_callback("/({$reg[0]})(.*?)({$reg[1]})/is",
                    [$this, 'closeTag'], $data);
            } while ($count && $count--); //递归解析，直到嵌套解析完毕
            return $data;
        } elseif (is_array($data)) {
            $num = count($data);
            if (preg_match("/{$reg[0]}/is", $data[$num - 2])) {
                //存在嵌套，进一步解析
                $count          = 1;
                $data[$num - 2] = preg_replace_callback("/({$reg[0]})(.*?)({$reg[1]})/is",
                    [$this, 'closeTag'], $data[$num - 2] . $data[$num - 1]);
                return $data[1] . $data[$num - 2];
            } else {
                //不存在嵌套，直接解析内容
                $parse          = '_' . $func;
                $data[$num - 2] = trim($data[$num - 2], "\r\n"); //去掉标签内容两端的换行符
                return $this->$parse($tag, $data);
            }
        }
    }
private function closeTag($data, $rule = '')
    {
        static $tag, $reg, $func, $count = 0;
        if (is_string($data)) {
            list($tag, $reg[0], $reg[1], $func) = $rule;
            do {
                $data = preg_replace_callback("/({$reg[0]})(.*?)({$reg[1]})/is",
                    [$this, 'closeTag'], $data);
            } while ($count && $count--); //递归解析，直到嵌套解析完毕
            return $data;
        } elseif (is_array($data)) {
            $num = count($data);
            if (preg_match("/{$reg[0]}/is", $data[$num - 2])) {
                //存在嵌套，进一步解析
                $count          = 1;
                $data[$num - 2] = preg_replace_callback("/({$reg[0]})(.*?)({$reg[1]})/is",
                    [$this, 'closeTag'], $data[$num - 2] . $data[$num - 1]);
                return $data[1] . $data[$num - 2];
            } else {
                //不存在嵌套，直接解析内容
                $parse          = '_' . $func;
                $data[$num - 2] = trim($data[$num - 2], "\r\n"); //去掉标签内容两端的换行符
                return $this->$parse($tag, $data);
            }
        }
    }
解析闭合标签，支持嵌套
@param  string $data 要解析的数据
@param  array  $rule 解析规则
@return string       解析后的内容