src/Valkyrja/Path/NativePathParser.php
protected function parsePath(string $path, array &$segments): array
    {
        /* @var array[] $params */
        // Get all matches for {paramName} and {paramName:regex} in the path
        preg_match_all(
            '/' . static::VARIABLE_REGEX . '/x',
            $path,
            $params
        );
        $regex        = $path;
        $paramsReturn = [];

        // Run through all matches
        foreach ($params[0] as $key => $param) {
            // Undo replacements made in parse foreach loop (see line 85)
            [$params[0][$key], $params[2][$key]] = str_replace(
                [')*?', ')?'],
                ['*]', ']'],
                [$params[0][$key], $params[2][$key]]
            );
            // Get the regex for this param
            $paramRegex = $this->getParamReplacement($key, $params);
            // Replace the matches with a regex
            $regex = str_replace($param, $paramRegex, $regex);
            // What to replace in the segment for this item
            $replace = '{' . $params[1][$key] . '}';

            // Set the param in the array of params to return
            $paramsReturn[$params[1][$key]] = [
                'replace' => $replace,
                'regex'   => $paramRegex,
            ];

            // Iterate through the segments
            foreach ($segments as $segmentKey => $segment) {
                // Replace this match with the replace text thus removing any regex
                // in the segment this fixes any regex with brackets from being
                // messed up in the splitSegments() method
                $segments[$segmentKey] = str_replace(
                    $params[0][$key],
                    $replace,
                    $segment
                );
            }
        }

        $regex = str_replace('/', '\/', $regex);
        $regex = '/^' . $regex . '$/';

        $segmentsReturn = $this->splitSegments($segments, ']');
        $segmentsReturn = $this->splitSegments($segmentsReturn, '<');
        $segmentsReturn = $this->splitSegments($segmentsReturn, '>');

        return [
            'regex'    => $regex,
            'params'   => $paramsReturn,
            'segments' => $segmentsReturn,
        ];
    }
protected function parsePath(string $path, array &$segments): array
    {
        /* @var array[] $params */
        // Get all matches for {paramName} and {paramName:regex} in the path
        preg_match_all(
            '/' . static::VARIABLE_REGEX . '/x',
            $path,
            $params
        );
        $regex        = $path;
        $paramsReturn = [];

        // Run through all matches
        foreach ($params[0] as $key => $param) {
            // Undo replacements made in parse foreach loop (see line 85)
            [$params[0][$key], $params[2][$key]] = str_replace(
                [')*?', ')?'],
                ['*]', ']'],
                [$params[0][$key], $params[2][$key]]
            );
            // Get the regex for this param
            $paramRegex = $this->getParamReplacement($key, $params);
            // Replace the matches with a regex
            $regex = str_replace($param, $paramRegex, $regex);
            // What to replace in the segment for this item
            $replace = '{' . $params[1][$key] . '}';

            // Set the param in the array of params to return
            $paramsReturn[$params[1][$key]] = [
                'replace' => $replace,
                'regex'   => $paramRegex,
            ];

            // Iterate through the segments
            foreach ($segments as $segmentKey => $segment) {
                // Replace this match with the replace text thus removing any regex
                // in the segment this fixes any regex with brackets from being
                // messed up in the splitSegments() method
                $segments[$segmentKey] = str_replace(
                    $params[0][$key],
                    $replace,
                    $segment
                );
            }
        }

        $regex = str_replace('/', '\/', $regex);
        $regex = '/^' . $regex . '$/';

        $segmentsReturn = $this->splitSegments($segments, ']');
        $segmentsReturn = $this->splitSegments($segmentsReturn, '<');
        $segmentsReturn = $this->splitSegments($segmentsReturn, '>');

        return [
            'regex'    => $regex,
            'params'   => $paramsReturn,
            'segments' => $segmentsReturn,
        ];
    }
Parse a path with no optionals.

@param string $path     The path
@param array  $segments The segments

@return array