src/Leevel/View/Parser.php
protected function findNodeTag(string &$compiled): void
    {
        // 设置一个栈
        $this->nodeStack = new Stack(['array']);

        // 判断是那种编译器
        $nodeType = true === $this->jsNode ? 'js' : 'node';

        // 所有一级节点名称
        foreach ($this->compilers[$nodeType] as $compilers => $tag) {
            // 处理一些正则表达式中有特殊意义的符号
            $names[] = $this->escapeRegexCharacter($compilers);
        }

        // 正则分析
        $tag = $this->getTag($nodeType);
        $names = implode('|', $names);
        $regex = "/{$tag['left']}\\s*(\\/?)(({$names})(:[^\\s".
            (true === $this->jsNode ? '' : '\\>').
            '\\}]+)?)(\\s[^'.
            (true === $this->jsNode ? '' : '>').
            "\\}]*?)?\\/?{$tag['right']}/isx";

        // 标签名称位置
        $nodeNameIndex = 2;

        // 标签顶级名称位置
        $nodeTopNameIndex = 3;

        // 尾标签斜线位置
        $tailSlasheIndex = 1;

        // 标签属性位置
        $tagAttributeIndex = 5;

        if (true === $this->jsNode) {
            $compiler = $this->compilers['js'];
        } else {
            $compiler = $this->compilers['node'];
        }

        // 依次创建标签对象
        if (preg_match_all($regex, $compiled, $res)) {
            $startPos = 0;

            foreach ($res[0] as $index => &$tagSource) {
                $nodeName = $res[$nodeNameIndex][$index];
                $nodeTopName = $res[$nodeTopNameIndex][$index];
                $nodeType = '/' === $res[$tailSlasheIndex][$index] ? 'tail' : 'head';

                // 将节点名称统一为小写
                $nodeName = strtolower($nodeName);
                $nodeTopName = strtolower($nodeTopName);

                $theme = [
                    'source' => $tagSource,
                    'name'   => $compiler[$nodeTopName],
                    'type'   => $nodeType,
                ];

                // 头标签的属性
                if ('head' === $nodeType) {
                    $theme['attribute'] = $res[$tagAttributeIndex][$index];
                } else {
                    $theme['attribute'] = '';
                }

                $theme['content'] = $theme['attribute'];
                $theme['position'] = $this->getPosition($compiled, $tagSource, $startPos);
                $startPos = $theme['position']['end'] + 1;
                $theme = $this->normalizeThemeStruct($theme);

                // 加入到标签栈
                $this->nodeStack->in($theme);
            }
        }
    }
protected function findNodeTag(string &$compiled): void
    {
        // 设置一个栈
        $this->nodeStack = new Stack(['array']);

        // 判断是那种编译器
        $nodeType = true === $this->jsNode ? 'js' : 'node';

        // 所有一级节点名称
        foreach ($this->compilers[$nodeType] as $compilers => $tag) {
            // 处理一些正则表达式中有特殊意义的符号
            $names[] = $this->escapeRegexCharacter($compilers);
        }

        // 正则分析
        $tag = $this->getTag($nodeType);
        $names = implode('|', $names);
        $regex = "/{$tag['left']}\\s*(\\/?)(({$names})(:[^\\s".
            (true === $this->jsNode ? '' : '\\>').
            '\\}]+)?)(\\s[^'.
            (true === $this->jsNode ? '' : '>').
            "\\}]*?)?\\/?{$tag['right']}/isx";

        // 标签名称位置
        $nodeNameIndex = 2;

        // 标签顶级名称位置
        $nodeTopNameIndex = 3;

        // 尾标签斜线位置
        $tailSlasheIndex = 1;

        // 标签属性位置
        $tagAttributeIndex = 5;

        if (true === $this->jsNode) {
            $compiler = $this->compilers['js'];
        } else {
            $compiler = $this->compilers['node'];
        }

        // 依次创建标签对象
        if (preg_match_all($regex, $compiled, $res)) {
            $startPos = 0;

            foreach ($res[0] as $index => &$tagSource) {
                $nodeName = $res[$nodeNameIndex][$index];
                $nodeTopName = $res[$nodeTopNameIndex][$index];
                $nodeType = '/' === $res[$tailSlasheIndex][$index] ? 'tail' : 'head';

                // 将节点名称统一为小写
                $nodeName = strtolower($nodeName);
                $nodeTopName = strtolower($nodeTopName);

                $theme = [
                    'source' => $tagSource,
                    'name'   => $compiler[$nodeTopName],
                    'type'   => $nodeType,
                ];

                // 头标签的属性
                if ('head' === $nodeType) {
                    $theme['attribute'] = $res[$tagAttributeIndex][$index];
                } else {
                    $theme['attribute'] = '';
                }

                $theme['content'] = $theme['attribute'];
                $theme['position'] = $this->getPosition($compiled, $tagSource, $startPos);
                $startPos = $theme['position']['end'] + 1;
                $theme = $this->normalizeThemeStruct($theme);

                // 加入到标签栈
                $this->nodeStack->in($theme);
            }
        }
    }
查找成对节点.

@param string $compiled