code: public function match($test)
  	{
  		// Generate pattern
  		$isArray	= [];
  		$pattern = preg_replace_callback(
  			"~/\{(?<arg>\w+)(?<arr>\[\])?\}(?<num>\?|\+|\*|\{[0-9,]+\})?~",
  			function($matches) use (&$isArray) {
  				
  				$name			= $matches["arg"];
  				$num			= $matches["num"] ?? "";
  				$isArray[$name]	= !empty($matches[2]);
  				return "(?<$name>(?:/[^\\s/?]+)$num)";
  			},
  			$this->url
  		);
  
  		// Pattern error
  		if (!$pattern || empty($pattern))
  		{
  			// Pattern error
  			error_log("pattern error: found in route with pattern: {$this->url}");
  			return false;
  		}
  
  		// Append start, parameters and end
  		$pattern = "^$pattern/?(?:\?.*)?$";
  
  		// Match
  		if (preg_match("~$pattern~", $test, $matches))
  		{
  			foreach ($matches as $name => $val)
  			{
  				// Decode url
  				$val = urldecode($val);
  				
  				// Discard non-associative indexes
  				if (is_int($name))
  				{
  					if ($name === 0) $this->args[$name] = $val;
  				}
  				else
  				{
  					// Get values as array or as string
  					$val = ltrim($val, "/");
  					$this->args[$name] = $isArray[$name] ? explode("/", $val) : $val;
  				}
  			}
  
  			// It's a match!
  			return true;
  		}
  
  		// Better luck next time!
  		return false;
  	}
docs: Determine if test string matches this route
  
  @param string $test test url string
  
  @return array