src/Parser.php
public static function split($pattern)
    {
        $segments = [];
        $len = strlen($pattern);
        $buffer = '';
        $opened = 0;
        for ($i = 0; $i < $len; $i++) {
            if ($pattern[$i] === '{') {
                do {
                    $buffer .= $pattern[$i++];
                    if ($pattern[$i] === '}') {
                        $buffer .= $pattern[$i];
                        break;
                    }
                } while ($i < $len);
            } elseif ($pattern[$i] === '[') {
                $opened++;
                if ($opened === 1) {
                    $segments[] = $buffer;
                    $buffer = '';
                } else {
                    $buffer .= $pattern[$i];
                }
            } elseif ($pattern[$i] === ']') {
                $opened--;
                if ($opened === 0) {
                    $greedy = '?';
                    if ($i < $len -1) {
                        if ($pattern[$i + 1] === '*' || $pattern[$i + 1] === '+') {
                            $greedy = $pattern[$i + 1];
                            $i++;
                        }
                    }
                    $segments[] = [$buffer, $greedy];
                    $buffer = '';
                } else {
                    $buffer .= $pattern[$i];
                }
            } else {
                $buffer .= $pattern[$i];
            }
        }
        if ($buffer) {
            $segments[] = $buffer;
        }
        if ($opened) {
            throw ParserException::squareBracketMismatch();
        }
        return $segments;
    }
public static function split($pattern)
    {
        $segments = [];
        $len = strlen($pattern);
        $buffer = '';
        $opened = 0;
        for ($i = 0; $i < $len; $i++) {
            if ($pattern[$i] === '{') {
                do {
                    $buffer .= $pattern[$i++];
                    if ($pattern[$i] === '}') {
                        $buffer .= $pattern[$i];
                        break;
                    }
                } while ($i < $len);
            } elseif ($pattern[$i] === '[') {
                $opened++;
                if ($opened === 1) {
                    $segments[] = $buffer;
                    $buffer = '';
                } else {
                    $buffer .= $pattern[$i];
                }
            } elseif ($pattern[$i] === ']') {
                $opened--;
                if ($opened === 0) {
                    $greedy = '?';
                    if ($i < $len -1) {
                        if ($pattern[$i + 1] === '*' || $pattern[$i + 1] === '+') {
                            $greedy = $pattern[$i + 1];
                            $i++;
                        }
                    }
                    $segments[] = [$buffer, $greedy];
                    $buffer = '';
                } else {
                    $buffer .= $pattern[$i];
                }
            } else {
                $buffer .= $pattern[$i];
            }
        }
        if ($buffer) {
            $segments[] = $buffer;
        }
        if ($opened) {
            throw ParserException::squareBracketMismatch();
        }
        return $segments;
    }
Splits a pattern in segments and patterns.
segments will be represented by string value and patterns by an array containing
the string pattern as first value and the greedy value as second value.

example:
`/user[/{id}]*` will gives `['/user', ['id', '*']]`

Unfortunately recursive regex matcher can't help here so this function is required.

@param string $pattern A route pattern.
@param array           The splitted pattern.