найти причину автоматического определения кодировки (UTF-8 против Windows-1252) - PullRequest
0 голосов
/ 11 февраля 2019

У меня есть CSV с контентом в кодировке UTF-8.Однако различные приложения и системы ошибочно обнаруживают кодировку CSV как Windows-1252, что нарушает все специальные символы в файле (например, Umlauts).

Я вижу, например, Sublime Text (в Windows)также автоматически обнаруживает неправильную кодировку Windows-1252 при первом открытии файла, показывая искаженный текст там, где должны быть специальные символы.

Когда я выбираю Открыть заново с кодировкой » UTF-8 , все будет выглядеть нормально, как и ожидалось.

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

CSV, о котором идет речь, на самом деле представляет собой автоматически сгенерированный экспорт продукта установки Magento 2.Недавно кодировка символов прервалась, и я сейчас пытаюсь выяснить, что произошло - отсюда мое расследование того, почему этот экспорт определяется как Windows-1252.

Есть ли надежный способ выяснить, почему автоматическое обнаружение приложенийкак Sublime Text предполагают неправильную кодировку символов?

1 Ответ

0 голосов
/ 14 февраля 2019

Это то, что я сделал в конце, чтобы выяснить, почему файл не был обнаружен как UTF-8, т.е. чтобы найти символы, которые не были закодированы в UTF-8.Поскольку PHP более легкодоступен для меня, я решил просто использовать следующий скрипт для принудительного преобразования всего, что не является UTF-8, в UTF-8, используя очень удобную библиотеку neitanod / forceutf8 .

$before = file_get_contents('export.csv');
$after = \ForceUTF8\Encoding::toUTF8($before);
file_put_contents('export.fixed.csv', $after);

Затем я использовал инструмент сравнения файлов, такой как Beyond Compare, чтобы сравнить два результирующих CSV-файла, чтобы легче было увидеть, какие символы изначально не были закодированы в UTF-8.

Это, в свою очередь,показал мне, что только один конкретный столбец экспорта был затронут.После дальнейшего изучения я обнаружил, что содержимое этого столбца было обработано в PHP следующим образом: preg_replace:

$value = preg_replace('/([^\pL0-9 -])+/', '', $value);

Использование \p в регулярном выражении имело неизвестный побочный эффект: все специальные символыбыли преобразованы в другую кодировку.Быстрое решение этой проблемы - использовать флаг u на регулярном выражении (см. справочник по модификаторам шаблонов регулярных выражений ).Это приводит к тому, что результирующее кодирование этого preg_replace будет UTF-8.Смотри также этот ответ .

...