Advent of code 2016/9
Ajax Direct

Answer 2ms

Part 1 : 107035 Part 2 : 11451628995
function solve($text, $recursive = false) {
    $size = 0;
    while (preg_match("/\(((\d+)x(\d+))\)/", $text, $marker, PREG_OFFSET_CAPTURE)) {
        // Add size of text before first marker found
        $size += $marker[0][1];

        // Get target sequence, uncompress it if necessary and add its size when repeated
        $sequence = substr($text, $marker[0][1] + strlen($marker[0][0]), $marker[2][0]);
        $sequence = $recursive ? solve($sequence, true) : strlen($sequence);
        $size += $sequence * $marker[3][0];

        // Keep only the part of the text that isn't uncompressed yet
        $text = substr($text, $marker[0][1] + strlen($marker[0][0]) + ($marker[2][0]));
    }

    return $size + strlen($text);
}

$solution_1 = solve($input);
$solution_2 = solve($input, true);