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;
    }