src/Template.php
static private function compile2(string $view): string
    {
        // 取模板内容
        $source = file_get_contents($view);

        // 短的开始标识
        $s = '<' . '?';

        // 长的开始标识
        $b = $s . 'php ';

        // 结束标识
        $e = '?' . '>';

        // 不允许出现PHP代码
        if (strpos($source, $s) !== false) {
            trigger_error('模板中不允许直接使用PHP:' . $view, E_USER_ERROR);
        }

        // 要替换 的内容
        $replace = [
            // 1.XML头
            '/{xml}/U' => $s . 'xml version="1.0" encoding="utf-8"' . $e,

            // 2.图片根路径
            '/{img}/U' => self::pathImg(),

            // 3.上传文件根路径
            '/{upload}/U' => self::pathUpload(),

            // 4.样式文件根路径
            '/{css}/U' => self::pathCss(),

            // 5.脚本文件根路径
            '/{js}/U' => self::pathJs(),

            // 6.通用,视图单元类的静态方法,便于开发者扩展
            '/{:(.*?\))}/U' => $s . '=icePHP\ViewUnit::\1' . $e,

            // 7.判断IE浏览器
            '/{ifIE}/' => $b . 'if(' . (self::isIE() ? '1' : '0') . '):' . $e,

            // 8.匹配 for 循环开始,与PHP语法一致
            '/{for\b(\(.*?\))}/U' => $b . 'for\1:' . $e,

            // 9.匹配 for 循环结束
            '/{endfor}/' => $b . 'endfor' . $e,
            '/{\/for}/' => $b . 'endfor' . $e,

            // 10.匹配 foreach 循环开始,与PHP语法一致
            '/{foreach\b(\(.*?\))}/U' => $b . 'foreach\1:' . $e,

            // 11.匹配 foreach 循环结束
            '/{endforeach}/' => $b . 'endforeach' . $e,
            '/{\/foreach}/' => $b . 'endforeach' . $e,

            // 12.匹配 while 循环开始
            '/{while\b(\(.*?\))}/U' => $b . 'while\1:' . $e,

            // 13.匹配 while 循环结束
            '/{endwhile}/' => $b . 'endwhile' . $e,
            '/{\/while}/' => $b . 'endwhile' . $e,

            // 14.匹配 if 开始,与PHP语法一致
            '/{if\b(\(.*?\))}/U' => $b . 'if\1:' . $e,

            // 15.匹配 elseif,与PHP语法一致
            '/{elseif\b(\(.*?\))}/U' => $b . 'elseif\1:' . $e,

            // 16.匹配 else
            '/{else}/' => $b . 'else:' . $e,

            // 17.匹配 if 结束
            '/{endif}/' => $b . 'endif' . $e,
            '/{\/if}/' => $b . 'endif' . $e,

            // 18.匹配 赋值 {assign($var=exp)}
            '/{assign\b\((.*?)\)}/U' => $b . '\1' . $e,
            '/{let\b\((.*?)\)}/U' => $b . '\1' . $e,

            // 19.匹配 原生代码开始
            '/{php}/' => $b,

            // 20.匹配 原生代码结束
            '/{\/php}/' => $e,

            // 21.匹配 子模板包含,语法 {include('子模板',参数数组)}
            '/{include\b(\(.*?\))}/U' => $b . 'icePHP\display\1' . $e,

            // 22.包含JS文件
            '/{js(\(.*?\))}/U' => $s . '=icePHP\Template::js\1' . $e,

            // 23.包含CSS文件
            '/{css(\(.*?\))}/U' => $s . '=icePHP\Template::css\1' . $e,

            // 24.default 默认值
            '/{default\((\$[^\,]*?)\,([^\)]*?)\)}/U' => "{$s}=!empty(\\1)?\\1:\\2{$e}",

            // 25. {?$xxx} 如果存在则显示
            '/{\?(\$.*?)}/U' => $s . '=(isset(\1) and \1!=="0000-00-00")?\1:""' . $e,

            // 26. 匹配 显示变量的值,与PHP语法一致
            '/{\$([^}]*?)}/U' => $s . '=$\1' . $e,

            // 27. 注释,不被编译
            '/{#[^}]*?}/U' => '',
            '/{\*[^(\*})]*?\*}/U' => '',

            // 对 url进行特殊处理
            '/{url(\(.*?\))}/U' => $s . '=icePHP\url\1' . $e,

            // 28. 匹配 显示函数返回值,与PHP语法一致
            '/{(.*?\))}/U' => $s . '=\1' . $e,

            //29.多语言翻译
            '/{\_\((.*?\))}/U' => $s . '=icePHP\translation(\1)' . $e,
        ];

        // 替换
        $target = preg_replace(array_keys($replace), array_values($replace), $source);

        // 如果不是调试模式,则去除首尾空格,去除HTML注释
        if (!isDebug()) {
            $target = preg_replace('/^\s*|\s*$/m', '', $target);
            $target = preg_replace('/<\!\-\-.*-->/m', '', $target);
        }

        // 返回编译结果
        return $target;
    }
static private function compile2(string $view): string
    {
        // 取模板内容
        $source = file_get_contents($view);

        // 短的开始标识
        $s = '<' . '?';

        // 长的开始标识
        $b = $s . 'php ';

        // 结束标识
        $e = '?' . '>';

        // 不允许出现PHP代码
        if (strpos($source, $s) !== false) {
            trigger_error('模板中不允许直接使用PHP:' . $view, E_USER_ERROR);
        }

        // 要替换 的内容
        $replace = [
            // 1.XML头
            '/{xml}/U' => $s . 'xml version="1.0" encoding="utf-8"' . $e,

            // 2.图片根路径
            '/{img}/U' => self::pathImg(),

            // 3.上传文件根路径
            '/{upload}/U' => self::pathUpload(),

            // 4.样式文件根路径
            '/{css}/U' => self::pathCss(),

            // 5.脚本文件根路径
            '/{js}/U' => self::pathJs(),

            // 6.通用,视图单元类的静态方法,便于开发者扩展
            '/{:(.*?\))}/U' => $s . '=icePHP\ViewUnit::\1' . $e,

            // 7.判断IE浏览器
            '/{ifIE}/' => $b . 'if(' . (self::isIE() ? '1' : '0') . '):' . $e,

            // 8.匹配 for 循环开始,与PHP语法一致
            '/{for\b(\(.*?\))}/U' => $b . 'for\1:' . $e,

            // 9.匹配 for 循环结束
            '/{endfor}/' => $b . 'endfor' . $e,
            '/{\/for}/' => $b . 'endfor' . $e,

            // 10.匹配 foreach 循环开始,与PHP语法一致
            '/{foreach\b(\(.*?\))}/U' => $b . 'foreach\1:' . $e,

            // 11.匹配 foreach 循环结束
            '/{endforeach}/' => $b . 'endforeach' . $e,
            '/{\/foreach}/' => $b . 'endforeach' . $e,

            // 12.匹配 while 循环开始
            '/{while\b(\(.*?\))}/U' => $b . 'while\1:' . $e,

            // 13.匹配 while 循环结束
            '/{endwhile}/' => $b . 'endwhile' . $e,
            '/{\/while}/' => $b . 'endwhile' . $e,

            // 14.匹配 if 开始,与PHP语法一致
            '/{if\b(\(.*?\))}/U' => $b . 'if\1:' . $e,

            // 15.匹配 elseif,与PHP语法一致
            '/{elseif\b(\(.*?\))}/U' => $b . 'elseif\1:' . $e,

            // 16.匹配 else
            '/{else}/' => $b . 'else:' . $e,

            // 17.匹配 if 结束
            '/{endif}/' => $b . 'endif' . $e,
            '/{\/if}/' => $b . 'endif' . $e,

            // 18.匹配 赋值 {assign($var=exp)}
            '/{assign\b\((.*?)\)}/U' => $b . '\1' . $e,
            '/{let\b\((.*?)\)}/U' => $b . '\1' . $e,

            // 19.匹配 原生代码开始
            '/{php}/' => $b,

            // 20.匹配 原生代码结束
            '/{\/php}/' => $e,

            // 21.匹配 子模板包含,语法 {include('子模板',参数数组)}
            '/{include\b(\(.*?\))}/U' => $b . 'icePHP\display\1' . $e,

            // 22.包含JS文件
            '/{js(\(.*?\))}/U' => $s . '=icePHP\Template::js\1' . $e,

            // 23.包含CSS文件
            '/{css(\(.*?\))}/U' => $s . '=icePHP\Template::css\1' . $e,

            // 24.default 默认值
            '/{default\((\$[^\,]*?)\,([^\)]*?)\)}/U' => "{$s}=!empty(\\1)?\\1:\\2{$e}",

            // 25. {?$xxx} 如果存在则显示
            '/{\?(\$.*?)}/U' => $s . '=(isset(\1) and \1!=="0000-00-00")?\1:""' . $e,

            // 26. 匹配 显示变量的值,与PHP语法一致
            '/{\$([^}]*?)}/U' => $s . '=$\1' . $e,

            // 27. 注释,不被编译
            '/{#[^}]*?}/U' => '',
            '/{\*[^(\*})]*?\*}/U' => '',

            // 对 url进行特殊处理
            '/{url(\(.*?\))}/U' => $s . '=icePHP\url\1' . $e,

            // 28. 匹配 显示函数返回值,与PHP语法一致
            '/{(.*?\))}/U' => $s . '=\1' . $e,

            //29.多语言翻译
            '/{\_\((.*?\))}/U' => $s . '=icePHP\translation(\1)' . $e,
        ];

        // 替换
        $target = preg_replace(array_keys($replace), array_values($replace), $source);

        // 如果不是调试模式,则去除首尾空格,去除HTML注释
        if (!isDebug()) {
            $target = preg_replace('/^\s*|\s*$/m', '', $target);
            $target = preg_replace('/<\!\-\-.*-->/m', '', $target);
        }

        // 返回编译结果
        return $target;
    }
预编译模板第二步

@param string $view
@return string todo (.*?) /U非贪婪模式