检测路由
@access public
@param  string $url 访问地址
@param  array $match 匹配路由变量
@param  bool $completeMatch 路由是否完全匹配
@return Dispatch|false
169385
public function checkRule($url, $match = null, $completeMatch = false)
    {
        if ($dispatch = $this->checkCrossDomain()) {
            // 允许跨域
            return $dispatch;
        }

        // 检查参数有效性
        if (!$this->checkOption($this->option)) {
            return false;
        }

        // 合并分组参数
        $option = $this->mergeGroupOptions();
        $url = $this->urlSuffixCheck($url, $option);

        if (is_null($match)) {
            $match = $this->match($url, $option, $completeMatch);
        }

        if (false !== $match) {
            // 检查前置行为
            if (isset($option['before']) && false === $this->checkBefore($option['before'])) {
                return false;
            }

            return $this->parseRule($this->rule, $this->route, $url, $option, $match);
        }

        return false;
    }
90575
private function match($url, $option, $completeMatch)
    {
        if (isset($option['complete_match'])) {
            $completeMatch = $option['complete_match'];
        }

        $pattern = array_merge($this->parent->getPattern(), $this->pattern);
        $depr = $this->router->config('app.pathinfo_depr');

        // 检查完整规则定义
        if (isset($pattern['__url__']) && !preg_match(0 === strpos($pattern['__url__'], '/') ? $pattern['__url__'] : '/^' . $pattern['__url__'] . '/', str_replace('|', $depr, $url))) {
            return false;
        }

        $var = [];
        $url = $depr . str_replace('|', $depr, $url);
        $rule = $depr . str_replace('/', $depr, $this->rule);

        if ($depr == $rule && $depr != $url) {
            return false;
        }

        if (false === strpos($rule, '<')) {
            if (0 === strcasecmp($rule, $url) || (!$completeMatch && 0 === strncasecmp($rule . $depr, $url . $depr, strlen($rule . $depr)))) {
                return $var;
            }
            return false;
        }

        $slash = preg_quote('/-' . $depr, '/');

        if ($matchRule = preg_split('/[' . $slash . ']?<\w+\??>/', $rule, 2)) {
            if ($matchRule[0] && 0 !== strncasecmp($rule, $url, strlen($matchRule[0]))) {
                return false;
            }
        }

        if (preg_match_all('/[' . $slash . ']?<?\w+\??>?/', $rule, $matches)) {
            $regex = $this->buildRuleRegex($rule, $matches[0], $pattern, $option, $completeMatch);

            try {
                if (!preg_match('/^' . $regex . ($completeMatch ? '$' : '') . '/u', $url, $match)) {
                    return false;
                }
            } catch (\Exception $e) {
                throw new Exception('route pattern error');
            }

            foreach ($match as $key => $val) {
                if (is_string($key)) {
                    $var[$key] = $val;
                }
            }
        }

        // 成功匹配后返回URL中的动态变量数组
        return $var;
    }
282560
private function uriMatchesPattern( $requestUrl, $pattern )
	{
		if ( $requestUrl == $pattern )
		{
			return true;
		}
		elseif ( @preg_match( $pattern, '' ) !== false )
		{
			return boolval( preg_match( $pattern, $requestUrl ) );
		}
		else
		{
			return false;
		}
	}
922341
public function match(string $url, array $filters = array()): bool{
		//Check filters
		foreach($filters as $key => $value){
			if(!isset($this->filters[$key]))
				return false;

			if(!in_array($value, $this->filters[$key]))
				return false;
		}
		
		//Check url
		$url = trim($url, '/');
		$path = preg_replace_callback('#:([\w]+)#', array($this, 'paramMatch'), $this->path);
		$regex = "#^$path$#i";
		if(!preg_match($regex, $url, $matches))
			return false;

		array_shift($matches);
		$this->matches = $matches;
		return true;
	}
213853
public function query($match)
    {
        $keys    = $this->index->getKeys();
        $matches = array_filter($keys, function($key) use ($match) {
            return preg_match("/{$match}/i", $key);
        });

        $results = [];
        foreach ($matches as $match) {
            $result = $this->get($match);
            $results[key($result)] = current($result);
        }

        return $results;
    }
25269
public function fullUrlIs($match)
    {
        $url = Request::fullUrl();

        if (Str::is($match, $url)) {
            return true;
        }

        return false;
    }
479925
private static function parseRegex($matches,$route,$regx) {
        // 获取路由地址规则
        $url   =  is_array($route)?$route[0]:$route;
        $url   =  preg_replace_callback('/:(\d+)/', function($match) use($matches){return $matches[$match[1]];}, $url); 
        if(0=== strpos($url,'/') || 0===strpos($url,'http')) { // 路由重定向跳转
            header("Location: $url", true,(is_array($route) && isset($route[1]))?$route[1]:301);
            exit;
        }else{
            // 解析路由地址
            $var  =  self::parseUrl($url);
            // 处理函数
            foreach($var as $key=>$val){
                if(strpos($val,'|')){
                    list($val,$fun) = explode('|',$val);
                    $var[$key]    =   $fun($val);
                }
            }
            // 解析剩余的URL参数
            $regx =  substr_replace($regx,'',0,strlen($matches[0]));
            if($regx) {
                preg_replace_callback('/(\w+)\/([^\/]+)/', function($match) use(&$var){
                    $var[strtolower($match[1])] = strip_tags($match[2]);
                }, $regx);
            }
            // 解析路由自动传入参数
            if(is_array($route) && isset($route[1])) {
                if(is_array($route[1])){
                    $params     =   $route[1];
                }else{
                    parse_str($route[1],$params);
                }
                $var   =   array_merge($var,$params);
            }
            $_GET   =  array_merge($var,$_GET);
        }
        return true;
    }
690388
public function match(
        /*# string */ $httpMethod,
        /*# string */ $uriPath,
        array $parameters = []
    )/*# :  bool */ {
        $this->initResult($httpMethod, $uriPath);
        $this->getResult()->setParameters($parameters);

        $param = ['result' => $this->result];
        if ($this->trigger(self::EVENT_BEFORE_MATCH, $param) &&
            $this->matchWithCollectors() &&
            $this->trigger(self::EVENT_AFTER_MATCH, $param)
        ) {
            return true;
        }
        return false;
    }
41141
function parse_matched (match, line) {
  var whole_match = match[0]
  var url_match = match[2]
  var start = match.index + whole_match.indexOf(url_match)

  return {
    start: start,
    end: start + url_match.length,
    match: url_match,
    line: line.line,
    column: start - line.index
  }
}
756808
public function map($method, $pattern, $call)
    {
        if ($this->vitex === null) {
            $this->vitex = Vitex::getInstance();
            $this->caseSensitive = $this->vitex->getConfig('router.case_sensitive');
        }
        $method = strtoupper($method);

        $matcher = $this->getPatternRegexp($pattern);
        /**
         * 请求方法
         * 路由匹配正则
         * 执行方法
         * 原始路由字符串
         * 路由应用
         * 路由别名
         * 方法
         */
        $this->_patterns[] = [$method, $matcher, $call, $pattern, $this->getRouteApp(), '', []];
        return $this;
    }
134025
public function buildComplete($url = null, $full = false) {
		if (is_array($url)) {
			$url = $this->addQueryStrings($url);
		}

		return parent::build($url, $full);
	}
194468
public boolean matches(URL url) {
        boolean matches = false;
        if(wildcardMatches(protocol, url.getProtocol()) && wildcardMatches(host, url.getHost()) && wildcardMatches(getPath(), url.getPath())) {
            matches = true;
        }
        return matches;
    }
227853
public function defaultSpaRobotsTxt($request, $match)
    {
        $name = Tenant_Service::setting('spa.default', 'not-found');
        $spa = Tenant_SPA::getSpaByName($name);
        if (! isset($spa)) {
            $spa = Tenant_SpaService::getNotfoundSpa();
        }
        $resourcePath = $spa->getResourcePath('robots.txt');
        $host = ($request->https ? 'https://' : 'http://') . $request->SERVER['HTTP_HOST'];
        return new Tenant_HTTP_Response_RobotsTxt($host, $resourcePath);
    }
70519
public function setMatchUrl($matchUrl)
    {
        $matchUrl = trim(str_replace('/', ' ', $matchUrl));
        $this->matchUrl = $matchUrl;
        return $this;
    }
429596
protected function checkParams(RouteMatch $match, $routeConfig)
    {
        if (!isset($routeConfig['params'])) {
            return true;
        }

        $params = (array) $routeConfig['params'];
        foreach ($params as $name => $value) {

            $param = $match->getParam($name, null);
            if (null === $param) {
                continue;
            }

            if (!$this->checkParam($param, $value)) {
                return false;
            }
        }

        return true;
    }
1179845
public function setMatch(string $match) : self
    {
        if (substr($match, 0, 1) == '^' || substr($match, -1) == '$') {
            throw new \InvalidArgumentException(
                sprintf("Can't set start & end line on match for '%s'", $match)
            );
        }

        $this->match = $match;

        return $this;
    }
942369
public function find($request, $match)
    {
        $builder = new Pluf_Paginator_Builder(new CMS_Content());
        return $builder->setRequest($request)->build();
    }