public static function findAll($string, $regex)
    {
        $count = preg_match_all($regex, $string, $matches, PREG_SET_ORDER);
        if (!$count) {
            return [];
        }

        $pos = 0;
        $groups = [];
        foreach ($matches as $group) {
            $captureBegin = 0;
            $match = array_shift($group);
            $matchBegin = strpos($string, $match, $pos);
            $captures = [
                [
                    'begin' => $matchBegin,
                    'end' => $matchBegin + strlen($match) - 1,
                    'token' => $match,
                ],
            ];
            foreach ($group as $capture) {
                $captureBegin = strpos($match, $capture, $captureBegin);
                $captures[] = [
                    'begin' => $matchBegin + $captureBegin,
                    'end' => $matchBegin + $captureBegin + strlen($capture) - 1,
                    'token' => $capture,
                ];
            }
            $groups[] = $captures;
            $pos += strlen($match) - 1;
        }

        return $groups;
    }