Создайте файл test.php
и запустите приведенный ниже код (сохраните файл с кодировкой UTF-8).
echo preg_replace("/./","X","Á");
Вы получите XX
(он должен вернуть только один X
, но вот и первая ошибка). PHP делает какие-то странные вещи с многобайтовыми числами.
Теперь запустите этот код:
echo preg_replace("/.$/","X","Á");
Вы получите �X
. Это связано с ошибкой выше, но по какой-то причине первый символ повреждается.
В любом случае, есть ли простой способ решить эту проблему? Мое текущее регулярное выражение намного сложнее, чем приведенное выше, конечно, вышеизложенное бесполезно, но это минимум для воспроизведения ошибки.
Проблема возникает потому, что функция 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
Какая версия PHP?