Универсальная и чистая кодировка UTF-8 (PHP) - PullRequest
3 голосов
/ 08 декабря 2011

Я хотел бы иметь возможность конвертировать любую кодировку для очистки UTF-8 за один вызов (мы используем PHP).

Это для ApacheSolr индексация;проблема в том, что XML Parser Solr использует (написанный на Java) выдает исключение всякий раз, когда встречается с недопустимым UTF-8.

Мы пробовали iconv (), но иногда он обрезает строку после предупреждения, теряя некоторые данные,даже с // TRANSLIT и / или // IGNORE .

utf8_encode () работает только с latin1.

Мы импортируем многодокументы из многих источников, использующие много кодировок, и нам нужен идеально чистый вывод UTF-8.Нас не волнуют вопросы времени / ресурсов.

Спасибо за ваши мудрые ответы!

1 Ответ

0 голосов
/ 08 декабря 2011
  • Вместо этого можно попробовать mb_convert_encoding и mb_detect_encoding.
  • При импорте этих документов вам действительно нужно кодирование содержимого или что-то еще.Если вы выполняете индексирование из Интернета, найдите заголовок типа содержимого и содержимое самого файла HTML.Всегда используйте это в качестве основного источника - возможно, вернитесь к обнаружению, но обнаружение - это просто предположение .
  • Если эти два варианта не помогли, я бы предложил написать свой собственный кодобнаружить недопустимые символы в потоке.Затем просто замените их и используйте iconv().

Причина, по которой iconv не продолжается после ошибки, довольно проста: в некоторых кодировках символов важно, чтобы байты читались правильно, потому что символ можетосновываться на нескольких байтах.UTF-8 компенсирует это, используя битовую маску, чтобы определить, когда выполняется символ, но не во всех кодировках это есть.В такой кодировке неправильный один байт означает, что остальная часть строки может быть искажена, а это не то, что вам нужно.(Я не совсем уверен, но вы сможете повторить это, взяв строку UTF-16 и удалив пятый байт в файле)

Эй, я даже проиллюстрирую проблему :-)Ниже приведен пример (в некотором роде) UTF-16, который использует 2 байта на символ.

[74 00] [65 00] [73 00] [74 00] = test

Теперь давайте удалим один байт - здесь это первый 0x00

[74 65] [00 73] [00 74] [00] = ....

У меня естьПонятия не имею, чем бы он стал на самом деле, но, как вы видите, он просто разбивает оставшуюся часть строки, как только пропускается один байт.Если вам повезет, вы будете индексировать по-китайски.

...