кодировка strlen() и UTF-8
предполагая кодировку UTF-8 и strlen () в PHP, возможно ли, что эта строка имеет длину 4?
меня интересует только strlen (), а не другие функции
это строка: 1ï $¿½2
я протестировал его на своем компьютере, и я проверил кодировку UTF-8, и ответ, который я получаю, - 6.
Я не вижу ничего в руководстве для strlen или чего-либо, что я читал на UTF-8, что объяснило бы, почему некоторые из символов выше будет считаться меньше одного.
PS: этот вопрос и ответ (4) исходит из макетного теста для ZCE, который я купил на Ebay.
PPS:пожалуйста, бросьте мне кость и проголосуйте за это. Я сделала домашнее задание. Заранее благодарю за все ответы и голоса.
6 ответов
строка, которую вы разместили, имеет шесть символов: $1�2 (знак доллара, цифра один, нижний регистр i с диаэрезисом, перевернутый вопросительный знак, одна половина дроби, цифра два)
Если strlen () был вызван с представлением UTF-8 этой строки, вы получите результат девяти (возможно, хотя есть несколько представлений с разной длиной).
однако, если бы мы должны были хранить эту строку как ISO 8859-1 или CP1252, у нас была бы шестибайтовая длинная последовательность, которая будьте легальны, как UTF-8. Переинтерпретация этих 6 байтов как UTF-8 приведет к 4 символам: $1�2 (знак доллара, цифра один, символ замены Юникода, цифра 2). То есть кодировка UTF-8 одного символа " � "идентична кодировке ISO-8859-1 трех символов"ï½½".
символ замены часто вставляется, когда декодер UTF-8 считывает данные, которые не являются допустимыми данными UTF-8.
похоже, что исходная строка была обработана через несколько слои неправильной интерпретации; с помощью декодера UTF-8 на данных, отличных от UTF-8 (производя $1�2), а затем тем, что вы использовали для анализа этих данных (производя $1�2).
Как насчет использования mb_strlen() ?
http://lt.php.net/manual/en/function.mb-strlen.php
но если вам нужно использовать strlen, можно настроить веб-сервер, установив mbstring.директива func_overload до 2, поэтому она автоматически заменит использование strlen на mb_strlen в ваших скриптах.
необходимо использовать Многобайтовую строковую функцию mb_strlen () как:
mb_strlen($string, 'UTF-8');
вероятно, что в какой-то момент между подготовкой вопроса и его чтением какой-то процесс исказил символы, отличные от ASCII, поэтому вопрос изначально был о какой-то строке с 4 символами в ней.
последовательность �
получается, когда вы кодируете замена символа U+FFFD ( � ) в UTF-8 и интерпретировать результат в latin1. Этот символ используется в качестве замены для байтовых последовательностей, которые не кодируют символ, когда например, чтение текста из файла. То, что произошло, вероятно, таково:
исходный вопрос, хранящийся в текстовом файле latin1, имел: ¢2
(вы можете заменить ¢ на любой символ без ASCII)
файл был прочитан программой, которая использовала UTF-8. Поскольку байт, соответствующий¢, не мог быть интерпретирован, программа заменила его и прочитала текст �2
. Затем этот текст был написан с использованием UTF-8, в результате чего \xEF\xBF\xBD2
в файле.
потом какой-то третий приходит программа, которая читает файл в latin1 и показывает �2
.
нет.
Я буду использовать доказательство противоречием.
strlen подсчитывает байты, поэтому с strlen 4, должно быть ровно 4 байта в этой строке.
кодировка UTF8 требуется не менее 1 байта на символ.
установлено, что:
- есть 4 байт
- персонаж представлен не менее, чем 1 байт
...тем не менее, у нас есть 6 письмена....это противоречие. Так что нет.
однако не совсем ясно, какой набор символов использует программное обеспечение для отображения (например, веб-браузер) для ввода строки. Он может использовать некоторую необычную схему кодирования, где символ может быть представлен менее чем 8 битами. Если это так, то 4 байта могут отображаться как 6 символов. Таким образом, строка может быть utf8, но браузер может решить интерпретировать ее как, скажем, некоторый 5-битный набор символов.
многие символы UTF-8 занимают несколько байтов вместо одного. Вот как построен UTF-8 (Вот как вы можете иметь так много символов в одном наборе).
попробовать mb_strlen()
вместо.