Advent of code 2016/7
Ajax Direct

Answer

Part 1 :
Part 2 :
// ==================================================
// > PART 1
// ==================================================
$solution_1 = $input->lines->filter(fn ($ip) =>
    preg_match("/(.)(?!\\1)(.)\\2\\1/", $ip) && !preg_match("/\[[^\]]*(.)(?!\\1)(.)\\2\\1[^\]]*\]/", $ip)
)->count();

// ==================================================
// > PART 2
// ==================================================
$solution_2 = $input->lines->map(function ($ip) {
    if (!preg_match_all("/(?=(([a-z])(?!\\2)([a-z])\\2))/", $ip, $abas, PREG_OFFSET_CAPTURE)) return false;

    foreach ($abas[1] as $i=>$aba) {
        // ABA is outside of []
        $before = substr($ip, 0, $aba[1]);
        if (substr_count($before, "[") != substr_count($before, "]")) continue;

        // Has BAB in []
        $bab = $abas[3][$i][0] . $abas[2][$i][0] . $abas[3][$i][0];
        if (preg_match("/\[[^\]]*".$bab."[^\]]*\]/", $ip)) {
            return [$ip, $aba, $bab];
        };
    }

    return false;
})->filter()->count();