Простая ошибка с регулярным выражением PHP

Создайте файл test.php и запустите приведенный ниже код (сохраните файл с кодировкой UTF-8).

echo preg_replace("/./","X","Á");

Вы получите XX (он должен вернуть только один X, но вот и первая ошибка). PHP делает какие-то странные вещи с многобайтовыми числами.

Теперь запустите этот код:

echo preg_replace("/.$/","X","Á");

Вы получите �X. Это связано с ошибкой выше, но по какой-то причине первый символ повреждается.

В любом случае, есть ли простой способ решить эту проблему? Мое текущее регулярное выражение намного сложнее, чем приведенное выше, конечно, вышеизложенное бесполезно, но это минимум для воспроизведения ошибки.

🤔 А знаете ли вы, что...
PHP можно использовать для создания графических диаграмм и графиков.


54
1

Ответ:

Решено

Проблема возникает потому, что функция preg_replace заменяет каждый символ во входной строке на "X". Символ "Á" рассматривается в PHP как многобайтовый символ, то есть он хранится в памяти как более одного байта (или части).

Когда preg_replace использует шаблон "/./", он соответствует каждому байту отдельно, а не всему "Á" символу. Таким образом, вместо замены "Á" на один "X", он заменяет каждую часть (байт) "Á" на "X", в результате чего получается "XX".

Чтобы исправить это, вам следует использовать регулярное выражение, которое работает с многобайтовыми символами. Так

echo preg_replace("/./u", "X", "Á");

Объяснение: добавление модификатора u указывает PHP обрабатывать строку как UTF-8.

Проблема со вторым кодом аналогична первой. Вот исправление для этого.

echo preg_replace("/.$/u", "X", "Á");

Онлайн исполнение: https://3v4l.org/RLYma