original_string: public function parseParamRoute(string $route, array $params, array $conf): array
      {
          $bak = $route;
          $noOptional = null;
  
          // 解析可选参数位
          if (false !== ($pos = \strpos($route, '['))) {
              // $hasOptional = true;
              $noOptional = \substr($route, 0, $pos);
              $withoutClosingOptionals = rtrim($route, ']');
              $optionalNum = \strlen($route) - \strlen($withoutClosingOptionals);
  
              if ($optionalNum !== \substr_count($withoutClosingOptionals, '[')) {
                  throw new \LogicException('Optional segments can only occur at the end of a route');
              }
  
              // '/hello[/{name}]' -> '/hello(?:/{name})?'
              $route = \str_replace(['[', ']'], ['(?:', ')?'], $route);
          }
  
          // quote '.','/' to '\.','\/'
          if (false !== \strpos($route, '.')) {
              // $route = preg_quote($route, '/');
              $route = \str_replace('.', '\.', $route);
          }
  
          // 解析参数，替换为对应的 正则
          if (\preg_match_all('#\{([a-zA-Z_][a-zA-Z0-9_-]*)\}#', $route, $m)) {
              /** @var array[] $m */
              $replacePairs = [];
  
              foreach ($m[1] as $name) {
                  $key = '{' . $name . '}';
                  $regex = $params[$name] ?? self::DEFAULT_REGEX;
  
                  // 将匹配结果命名 (?P<arg1>[^/]+)
                  $replacePairs[$key] = '(?P<' . $name . '>' . $regex . ')';
                  // $replacePairs[$key] = '(' . $regex . ')';
              }
  
              $route = \strtr($route, $replacePairs);
          }
  
          // 分析路由字符串是否是有规律的
          $first = null;
          $conf['regex'] = '#^' . $route . '$#';
  
          // first node is a normal string
          // e.g '/user/{id}' first: 'user', '/a/{post}' first: 'a'
          if (\preg_match('#^/([\w-]+)/[\w-]*/?#', $bak, $m)) {
              $first = $m[1];
              $conf['start'] = $m[0];
  
              return [$first, $conf];
          }
  
          // first node contain regex param '/hello[/{name}]' '/{some}/{some2}/xyz'
          $include = null;
  
          if ($noOptional) {
              if (\strpos($noOptional, '{') === false) {
                  $include = $noOptional;
              } else {
                  $bak = $noOptional;
              }
          }
  
          if (!$include && \preg_match('#/([\w-]+)/?[\w-]*#', $bak, $m)) {
              $include = $m[0];
          }
  
          $conf['include'] = $include;
  
          return [$first, $conf];
      }
code: public function parseParamRoute(string $route, array $params, array $conf): array
      {
          $bak = $route;
          $noOptional = null;
  
          // 解析可选参数位
          if (false !== ($pos = \strpos($route, '['))) {
              // $hasOptional = true;
              $noOptional = \substr($route, 0, $pos);
              $withoutClosingOptionals = rtrim($route, ']');
              $optionalNum = \strlen($route) - \strlen($withoutClosingOptionals);
  
              if ($optionalNum !== \substr_count($withoutClosingOptionals, '[')) {
                  throw new \LogicException('Optional segments can only occur at the end of a route');
              }
  
              // '/hello[/{name}]' -> '/hello(?:/{name})?'
              $route = \str_replace(['[', ']'], ['(?:', ')?'], $route);
          }
  
          // quote '.','/' to '\.','\/'
          if (false !== \strpos($route, '.')) {
              // $route = preg_quote($route, '/');
              $route = \str_replace('.', '\.', $route);
          }
  
          // 解析参数，替换为对应的 正则
          if (\preg_match_all('#\{([a-zA-Z_][a-zA-Z0-9_-]*)\}#', $route, $m)) {
              /** @var array[] $m */
              $replacePairs = [];
  
              foreach ($m[1] as $name) {
                  $key = '{' . $name . '}';
                  $regex = $params[$name] ?? self::DEFAULT_REGEX;
  
                  // 将匹配结果命名 (?P<arg1>[^/]+)
                  $replacePairs[$key] = '(?P<' . $name . '>' . $regex . ')';
                  // $replacePairs[$key] = '(' . $regex . ')';
              }
  
              $route = \strtr($route, $replacePairs);
          }
  
          // 分析路由字符串是否是有规律的
          $first = null;
          $conf['regex'] = '#^' . $route . '$#';
  
          // first node is a normal string
          // e.g '/user/{id}' first: 'user', '/a/{post}' first: 'a'
          if (\preg_match('#^/([\w-]+)/[\w-]*/?#', $bak, $m)) {
              $first = $m[1];
              $conf['start'] = $m[0];
  
              return [$first, $conf];
          }
  
          // first node contain regex param '/hello[/{name}]' '/{some}/{some2}/xyz'
          $include = null;
  
          if ($noOptional) {
              if (\strpos($noOptional, '{') === false) {
                  $include = $noOptional;
              } else {
                  $bak = $noOptional;
              }
          }
  
          if (!$include && \preg_match('#/([\w-]+)/?[\w-]*#', $bak, $m)) {
              $include = $m[0];
          }
  
          $conf['include'] = $include;
  
          return [$first, $conf];
      }
code_tokens: public function parseParamRoute ( string $ route , array $ params , array $ conf ) : array { $ bak = $ route ; $ noOptional = null ; // 解析可选参数位 if ( false !== ( $ pos = \ strpos ( $ route , '[' ) ) ) { // $hasOptional = true; $ noOptional = \ substr ( $ route , 0 , $ pos ) ; $ withoutClosingOptionals = rtrim ( $ route , ']' ) ; $ optionalNum = \ strlen ( $ route ) - \ strlen ( $ withoutClosingOptionals ) ; if ( $ optionalNum !== \ substr_count ( $ withoutClosingOptionals , '[' ) ) { throw new \ LogicException ( 'Optional segments can only occur at the end of a route' ) ; } // '/hello[/{name}]' -> '/hello(?:/{name})?' $ route = \ str_replace ( [ '[' , ']' ] , [ '(?:' , ')?' ] , $ route ) ; } // quote '.','/' to '\.','\/' if ( false !== \ strpos ( $ route , '.' ) ) { // $route = preg_quote($route, '/'); $ route = \ str_replace ( '.' , '\.' , $ route ) ; } // 解析参数，替换为对应的 正则 if ( \ preg_match_all ( '#\{([a-zA-Z_][a-zA-Z0-9_-]*)\}#' , $ route , $ m ) ) { /** @var array[] $m */ $ replacePairs = [ ] ; foreach ( $ m [ 1 ] as $ name ) { $ key = '{' . $ name . '}' ; $ regex = $ params [ $ name ] ?? self :: DEFAULT_REGEX ; // 将匹配结果命名 (?P<arg1>[^/]+) $ replacePairs [ $ key ] = '(?P<' . $ name . '>' . $ regex . ')' ; // $replacePairs[$key] = '(' . $regex . ')'; } $ route = \ strtr ( $ route , $ replacePairs ) ; } // 分析路由字符串是否是有规律的 $ first = null ; $ conf [ 'regex' ] = '#^' . $ route . '$#' ; // first node is a normal string // e.g '/user/{id}' first: 'user', '/a/{post}' first: 'a' if ( \ preg_match ( '#^/([\w-]+)/[\w-]*/?#' , $ bak , $ m ) ) { $ first = $ m [ 1 ] ; $ conf [ 'start' ] = $ m [ 0 ] ; return [ $ first , $ conf ] ; } // first node contain regex param '/hello[/{name}]' '/{some}/{some2}/xyz' $ include = null ; if ( $ noOptional ) { if ( \ strpos ( $ noOptional , '{' ) === false ) { $ include = $ noOptional ; } else { $ bak = $ noOptional ; } } if ( ! $ include && \ preg_match ( '#/([\w-]+)/?[\w-]*#' , $ bak , $ m ) ) { $ include = $ m [ 0 ] ; } $ conf [ 'include' ] = $ include ; return [ $ first , $ conf ] ; }
docstring: parse param route
  @param string $route
  @param array $params
  @param array $conf
  @return array
  @throws \LogicException
docstring_tokens: parse param route