处理 编码时的 匹配后处理
@param $pattern string 转义后的路径
@param array $params 参数
@return string 继续 转义后的路径
975432
static private function encodeMatched(string $pattern, array $params): string
    {
        // 参数替换进去
        $others = [];
        foreach ($params as $k => $v) {
            if (strstr($pattern, '{' . $k . '}') !== false) {
                $pattern = str_replace('{' . $k . '}', $v, $pattern);
            } else {
                $others[$k] = $v;
            }
        }

        //剩下的参数附加上去
        $pattern = self::urlAppend($pattern, $others);

        return trim($pattern, '?');
    }
1019335
public function post(string $pattern, array $param) : void
    {
        $this->call('post', $pattern, $param[0], $param[1], $param);
    }
455920
private function find($pattern, $offset = null, $normal = false)
    {
        $source = $this->source;
        $offset = ($offset === null) ? $source->cursor : $offset;
        if ($offset >= $source->bound) {
            $this->addError('The scope of the parsing template is beyond the length of the template content');
            return null;
        }
        $content = $source->substring($offset, $source->bound);
        if (!preg_match($pattern, $content, $match, PREG_OFFSET_CAPTURE)) {
            return null;
        }
        $ret = $match[0];
        $length = strlen($ret[0]);
        if ($length == 0) {
            return null;
        }
        $start = $offset + $ret[1];
        $end = $start + $length;
        if ($normal) {
            return ['val' => $ret[0], 'idx' => 0, 'start' => $start, 'end' => $end, 'len' => $length];
        }
        $match = array_filter($match, function ($item) {
            return $item[1] != -1;
        });
        foreach ($match as $k => &$v) {
            $v[2] = $k - 1;
        }
        $ret = end($match);
        return ['val' => $ret[0], 'idx' => $ret[2], 'start' => $start, 'end' => $end, 'len' => $length];
    }
490085
public function match($pattern, array $patterns = []) {
        return $this->matcher->match(
            $this->addLeadingSlash($pattern), $this->getPath(), $patterns
        );
    }
32731
private function getMethods($pattern = "/^action_/") {
		$methos = get_class_methods($this->class);
		$actions = array();

		foreach ($methos as $methodName) {
			if (preg_match($pattern, $methodName)) {
				array_push($actions, $methodName);
			}
		}
		return $actions;
	}
759832
public function select(string $pattern): \Iterator
    {
        //游标,每次查询必须从0开始
        $iterator = NULL;
        while (true) {
            //查询并更新游标
            $ret = $this->handle->zScan($this->name, $iterator, $pattern, 10);

            //没有更多数据了
            if (false === $ret) {
                break;
            }

            //逐个返回
            foreach ($ret as $key => $val) {
                yield [$key => $val];
            }
        }
    }
1345872
private function getOptionByRegExpr(string $pattern): array
    {
        $purgedArgs = $this->getRawArgs(true);
        return preg_grep("/" . $pattern . "/", $purgedArgs);
    }
650489
public function parsePattern($pattern)
    {
        $withoutClosing = rtrim($pattern, "]");
        $closingNumber  = strlen($pattern) - strlen($withoutClosing);

        $segments = preg_split("~" . self::DYNAMIC_REGEX . "(*SKIP)(*F)|\[~x", $withoutClosing);
        $this->parseSegments($segments, $closingNumber, $withoutClosing);

        return $this->buildSegments($segments);
    }
50027
public static String format(String pattern, Object... arguments) {
        String msg = pattern;
        if (arguments != null) {
            for (int index = 0; index < arguments.length; index++) {
                msg = msg.replaceAll("\\{" + (index + 1) + "\\}", String.valueOf(arguments[index]));
            }
        }
        return msg;
    }
186354
public function getKeys($pattern = null)
    {
        $keys = $this->get('__stored_keys__', []);
        if (is_null($pattern)) {
            return $keys;
        }

        $matches = [];
        $pattern = $this->_normalizePattern($pattern);
        foreach ($keys as $key) {
            if (preg_match($pattern, $key)) {
                $matches[] = $key;
            }
        }

        return $matches;
    }
1095056
protected function convertPattern($pattern)
    {
        $prefix = 0 === strpos($pattern, '!') ? '!' : '';
        $searchPattern = trim(ltrim($pattern, '!'), '/');
        $pattern = $prefix.$searchPattern;

        if (\in_array($searchPattern, array('*', '*.*'), true)) {
            $this->doAddPattern($prefix.'.*');
        } elseif (0 === strpos($searchPattern, '**/')) {
            $this->doAddPattern($prefix.'**/'.$searchPattern);
            $this->doAddPattern($prefix.substr($searchPattern, 3));
        } else {
            $this->convertPatternStep2($prefix, $searchPattern, $pattern);
        }

        return $pattern;
    }
1147361
protected function extractParameterValues($pattern, $path, array $patterns = []) {
        $path = $this->addTrailingSlash($path);
        $matches = [];

        $pattern = $this->createRegexPattern($pattern, $patterns);
        preg_match_all($pattern, $path, $matches);
        array_shift($matches);

        $values = $this->processParameterValues($matches);

        return $values;
    }
1208799
public function path($pattern = null)
    {
        if (isset($pattern)) {
            return preg_match("~$pattern~i", $this->path) === 1;
        }

        return $this->path;
    }
414735
private function getMatchStringParameterIndices($matchString, $pattern)
    {
        $indices = [];

        foreach ($pattern as $part) {
            if (!$this->isTokenPatternPart($part)) {
                $offset = 0;

                foreach ($indices as $currentIndex) {
                    $prefix = $currentIndex['prefix'];

                    if ($prefix == $part || substr_count($prefix, $part) || substr_count($part, $prefix)) {
                        $offset = $currentIndex['index'];
                    }
                }

                $indices[] = [
                    'prefix' => $part,
                    'index' => strpos($matchString, $part, $offset) + strlen($part)
                ];
            }
        }

        return $indices;
    }
915837
public static function tokenizePattern($pattern, $isHost = false, array $requirements = [], array $defaults = [])
    {
        // left pad pattern with separator
        if (!$isHost && false === self::isSeparator(substr($pattern, 0, 1))) {
            $pattern = '/'.$pattern;
        }

        list ($path, ) = $splt = array_pad(preg_split('#\{\w+\??\}#', $pattern), 1, '/');

        if (2 > count($splt)) {
            return [new Text($path)];
        }

        $separator = $isHost ? '.' : '/';
        $matchDel = join('|', array_map('preg_quote', str_split(Ps::SEPARATORS), str_split(
            str_repeat(Ps::EXP_DELIM, strlen(Ps::SEPARATORS))
        )));

        $expr = Ps::EXP_DELIM.sprintf(
            self::VAR_REGEXP,
            $matchDel,
            preg_quote(self::L_DELIM, Ps::EXP_DELIM),
            preg_quote(self::R_DELIM, Ps::EXP_DELIM)
        ).Ps::EXP_DELIM.'x';

        preg_match_all($expr, $pattern, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);

        $pos    = 0;
        $plen   = strlen($pattern);
        $nlen   = count($matches) - 1;
        $tokens = [];

        foreach ($matches as $i => $match) {
            // right hand delimiter, not always present
            $rdel = (!isset($match['rdel']) || -1 === $match['rdel'][1]) ? null : $match['rdel'];
            $ldel = -1 === $match['ldel'][1] ? null : $match['ldel'];
            $var  = -1 === $match['var'][1] ? null : $match['var'];
            $opt  = 0 === strcmp('?', substr($match[0][0], -2, 1));

            $default    = isset($defaults[$var[0]]) ? $defaults[$var[0]] : null;
            $constraint = isset($requirements[$var[0]]) ? $requirements[$var[0]] : null;

            $offset     = $match[0][1];

            // add preceeding text
            if (0 !== strlen($str = substr($pattern, $pos, $offset - $pos))) {
                $text = new Text($str, $lt = self::lastToken($tokens));
                self::pushTokens($text, $lt, $tokens);
            }

            // add left hand delimiter
            if (null !== $ldel) {
                $delim = new Delimiter($ldel[0], $lt = self::lastToken($tokens));
                self::pushTokens($delim, $lt, $tokens);
            }

            $opt = null === $default ? $opt : true;

            // add variable
            $tVar = new Variable($var[0], !$opt, $constraint, $lt = self::lastToken($tokens), null, $separator);
            self::pushTokens($tVar, $lt, $tokens);

            // add right hand delimiter
            if (null !== $rdel) {
                $delim = new Delimiter($rdel[0], $lt = self::lastToken($tokens));
                self::pushTokens($delim, $lt, $tokens);
            }

            // update current position
            $pos = $offset + strlen($match[0][0]);

            // add trailing text.
            if ($nlen === $i && $plen !== $pos) {
                $tail = substr($pattern, -($plen - $pos));

                if (0 !== strlen($tail)) {
                    $t = new Text($tail, $lt = self::lastToken($tokens));
                    self::pushTokens($t, $lt, $tokens);
                }
            }
        }

        return $tokens;
    }
1287848
public function getTemplatesByPattern($pattern)
    {
        $templates = array();
        foreach ($this->manageableExt->keys() as $ext) {
            $templates = array_merge($templates, parent::getTemplatesByPattern($pattern.$ext));
        }

        return $templates;
    }
1071427
private function parseRule($pattern)
    {
        $matcher = $pattern;
        $matcher = trim($matcher, '/');
        if (!$matcher) {
            return '|^/$|';
        }
        if ($matcher === '*') {
            return '|^.*$|i';
        } else {
            //替换 *为匹配除了 /分组之外的所有内容
            $matcher = str_replace('*', '[^\/]*', $matcher);
        }

        $slices = $this->route->getSlice($matcher);
        foreach ($slices as list($slice, $reg)) {
            $matcher = str_replace(':' . $slice, $reg, $matcher);
        }
        $matcher = '|^' . $matcher . '$|i';
        return $matcher;
    }