Почему буква 'i' ломает мой регулярное выражение в preg_replace_callback, но работает в JavaScript?

Я столкнулся с непонятной проблемой при использовании регулярных выражений в PHP. Мой код не выводит ничего в терминал:

<?php
$html = '<a href="example.com" title="Какой-то текст с буквой i внутри">Ссылка</a>';

echo preg_replace_callback(
    '/<a(\s[^>]+)* href="([^"]+)"(\s[^>]+)*>/i',
    function ($matches) {
        var_dump($matches);
        return $matches[0];
    },
    $html
);

Странно, но если я уберу букву ‘i’ из текста в атрибуте title, все начинает работать. Например, если заменить слово “внутри” на “внутр”, код выполняется без ошибок.

Что я упускаю в своем регулярном выражении? Почему буква ‘i’ так влияет на его работу?

При этом аналогичный код на JavaScript работает без проблем:

'<a href="example.com" title="Какой-то текст с буквой i внутри">Ссылка</a>'.match(/<a(\s[^>]+)* href="([^"]+)"(\s[^>]+)*>/i);

Как это объяснить и как исправить проблему в PHP?

Попробуй использовать модификатор /u для поддержки юникода. Еще можно попробовать заменить \s на [\s\S] - это позволит захватить любые символы, включая переносы строк. Вот так:

‘/<a([\s\S][^>]+)* href="([^"]+)"([\s\S][^>]+)*>/iu’

Если не сработает, может проблема в кодировке файла? Проверь, что он в UTF-8 без BOM.

Скорее всего проблема в том, что PHP по умолчанию использует PCRE движок для регулярок, который чувствителен к юникоду. Попробуй добавить модификатор u в конце выражения:

‘/<a(\s[^>]+)* href=“([^”]+)"(\s[^>]+)*>/iu’

Это включит поддержку юникода и должно решить проблему с буквой ‘i’. Еще совет - используй инструменты типа regex101.com для отладки регулярок, очень помогает.