Ответ 1
Убедитесь, что браузер и редактор используют кодировку UTF-8 вместо ISO-8859-1/Windows-1252.
Или используйте ’
.
’
отображается на моей странице вместо '
.
У меня есть Content-Type
, установленный в UTF-8
как в теге <head>
, так и в моих HTTP-заголовках:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
Кроме того, мой браузер настроен на Unicode (UTF-8)
:
Итак, в чем проблема, и как я могу ее исправить?
Убедитесь, что браузер и редактор используют кодировку UTF-8 вместо ISO-8859-1/Windows-1252.
Или используйте ’
.
Итак, какая проблема,
Это символ ’
(RIGHT SINGLE QUOTATION MARK
- U + 2019), который был закодирован как CP-1252 вместо UTF-8. Если вы проверите таблицу encodings, вы увидите, что этот символ находится в UTF-8, состоящий из байтов 0xE2
, 0x80
и 0x99
. Если вы проверите компоновку кодовой страницы CP-1252, вы увидите, что каждый из этих байтов обозначает отдельные символы â
, €
и ™
.
и как его исправить?
Используйте UTF-8 вместо CP-1252 для чтения, записи, хранения и отображения символов.
У меня есть Content-Type, установленный в UTF-8 как в теге
<head>
, так и в моих HTTP-заголовках:<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
Это только указывает клиенту, какую кодировку использовать для интерпретации и отображения символов. Это не дает указания вашей собственной программе, которую кодировка должна использовать для чтения, записи, хранения и отображения символов. Точный ответ зависит от используемой серверной платформы/базы данных/языка программирования. Обратите внимание, что тот, который установлен в заголовке ответа HTTP, имеет приоритет над метатегами HTML. Метатег HTML будет использоваться только тогда, когда страница будет открыта из локальной файловой системы диска, а не из HTTP.
Кроме того, мой браузер настроен на
Unicode (UTF-8)
:
Это только заставляет клиента кодирование использовать для интерпретации и отображения символов. Но проблема в том, что вы уже отправляете ’
(закодированный в UTF-8) клиенту вместо ’
. Клиент правильно отображает ’
с использованием кодировки UTF-8. Если клиент был неправильно проинсталлирован для использования, например, ISO-8859-1, скорее всего, вы видели ââ¬â¢
.
Я использую ASP.NET 2.0 с базой данных.
Это наиболее вероятно, где ваша проблема. Вам нужно проверить с помощью независимого инструмента базы данных, как выглядят данные.
Если присутствует символ ’
, значит, вы неправильно подключаетесь к базе данных. Чтобы использовать UTF-8, необходимо указать соединитель базы данных.
Если ваша база данных содержит ’
, то это ваша база данных, которая испортилась. Скорее всего, таблицы не настроены на использование UTF-8
. Вместо этого они используют кодировку по умолчанию базы данных, которая зависит от конфигурации. Если это ваша проблема, достаточно просто изменить таблицу для использования UTF-8. Если ваша база данных не поддерживает это, вам нужно будет воссоздать таблицы. Хорошая практика - установить кодировку таблицы при ее создании.
Скорее всего, вы используете SQL Server, но здесь есть код MySQL (скопирован из в эту статью):
CREATE DATABASE db_name CHARACTER SET utf8;
CREATE TABLE tbl_name (...) CHARACTER SET utf8;
Если ваша таблица, однако, уже UTF-8, вам нужно сделать шаг назад. Кто или что там помещает данные. Вот в чем проблема. Одним из примеров может быть форма представления HTML-формы, которые неправильно кодируются/декодируются.
Вот еще несколько ссылок, чтобы узнать больше о проблеме:
У меня есть некоторые документы, где …
показывался как …
и ê
показывался как ê
. Вот как это получилось (код python):
# Adam edits original file using windows-1252
windows = '\x85\xea'
# that is HORIZONTAL ELLIPSIS, LATIN SMALL LETTER E WITH CIRCUMFLEX
# Beth reads it correctly as windows-1252 and writes it as utf-8
utf8 = windows.decode("windows-1252").encode("utf-8")
print(utf8)
# Charlie reads it *incorrectly* as windows-1252 writes a twingled utf-8 version
twingled = utf8.decode("windows-1252").encode("utf-8")
print(twingled)
# detwingle by reading as utf-8 and writing as windows-1252 (it really utf-8)
detwingled = twingled.decode("utf-8").encode("windows-1252")
assert utf8==detwingled
Чтобы исправить проблему, я использовал код python следующим образом:
with open("dirty.html","rb") as f:
dt = f.read()
ct = dt.decode("utf8").encode("windows-1252")
with open("clean.html","wb") as g:
g.write(ct)
(Поскольку кто-то вставил измененную версию в правильный документ UTF-8, мне на самом деле пришлось извлечь только измененную часть, отделить ее и вставить обратно. Для этого я использовал BeautifulSoup.)
Скорее всего, у вас есть Charlie в создании контента, чем в конфигурации веб-сервера. Вы также можете заставить свой веб-браузер закрутить страницу, выбрав кодировку windows-1252 для документа utf-8. Ваш веб-браузер не может размещать документ, сохраненный Чарли.
Примечание: одна и та же проблема может возникнуть с любой другой однобайтовой кодовой страницей (например, latin-1) вместо windows-1252.
Если ваш тип контента уже UTF8, то, скорее всего, данные уже поступают в неправильную кодировку. Если вы получаете данные из базы данных, убедитесь, что соединение с базой данных использует UTF-8.
Если это данные из файла, убедитесь, что файл правильно закодирован как UTF-8. Обычно вы можете установить это в диалоговом окне "Сохранить как..." редактора по вашему выбору.
Если данные уже нарушены, когда вы просматриваете их в исходном файле, скорее всего, это был файл UTF-8, но где-то на пути он был сохранен в неправильной кодировке.
’
(кодировка Unicode U+2019 RIGHT SINGLE QUOTATION MARK
) кодируется в UTF-8 в виде байтов:
0xE2 0x80 0x99
.
’
(кодировки Unicode U+00E2 U+20AC U+2122
) кодируется в UTF-8 в виде байтов:
0xC3 0xA2
0xE2 0x82 0xAC
0xE2 0x84 0xA2
.
Это байты, которые ваш браузер фактически получает, чтобы создать ’
при обработке как UTF-8.
Это означает, что ваши исходные данные проходят через два конвертации кодировки перед отправкой в браузер:
Исходный символ ’
(U+2019
) сначала кодируется как байты UTF-8:
0xE2 0x80 0x99
тогда эти отдельные байты были неправильно интерпретированы и декодированы в Unicode codecoints U+00E2 U+20AC U+2122
одним из кодировок Windows-125X (1252, 1254, 1256 и 1258). Все карты 0xE2 0x80 0x99
до U+00E2 U+20AC U+2122
), а затем эти кодовые точки кодируются как байты UTF-8:
0xE2
→ U+00E2
→ 0xC3 0xA2
0x80
→ U+20AC
→ 0xE2 0x82 0xAC
0x99
→ U+2122
→ 0xE2 0x84 0xA2
Вам нужно найти, где выполняется дополнительное преобразование на шаге 2 и удалять его.
У вас есть несоответствие в кодировке вашего символа; ваша строка кодируется в одной кодировке (UTF-8), и все, что интерпретирует эту страницу, использует другую (например, ASCII).
Всегда указывайте свою кодировку в своих заголовках http и убедитесь, что это соответствует вашему определению кода кодирования.
Пример HTTP-заголовка:
Content-Type text/html; charset=utf-8
<configuration>
<system.web>
<globalization
fileEncoding="utf-8"
requestEncoding="utf-8"
responseEncoding="utf-8"
culture="en-US"
uiCulture="de-DE"
/>
</system.web>
</configuration>
Это иногда происходит, когда строка преобразуется из Windows-1252 в UTF-8 дважды.
У нас это было в приложении Zend/PHP/MySQL, где такие символы появлялись в базе данных, вероятно, из-за подключения MySQL, не задающего правильный набор символов. Нам пришлось:
Убедитесь, что Zend и PHP обменивались данными с базой данных в UTF-8 (по умолчанию не был)
Восстановите сломанные символы несколькими запросами SQL, такими как...
UPDATE MyTable SET
MyField1 = CONVERT(CAST(CONVERT(MyField1 USING latin1) AS BINARY) USING utf8),
MyField2 = CONVERT(CAST(CONVERT(MyField2 USING latin1) AS BINARY) USING utf8);
Сделайте это для использования как можно большего количества таблиц/столбцов.
Вы также можете исправить некоторые из этих строк в PHP, если это необходимо. Обратите внимание, что поскольку символы были закодированы дважды, нам действительно нужно сделать обратное преобразование из UTF-8 обратно в Windows-1252, что сначала смутило меня.
mb_convert_encoding('’', 'Windows-1252', 'UTF-8'); // returns ’
Если кто-то получил эту ошибку на веб-сайте WordPress, вам нужно изменить wars-конфигурацию db charset:
define('DB_CHARSET', 'utf8mb4_unicode_ci');
вместо:
define('DB_CHARSET', 'utf8mb4');
У вас должен быть текст для копирования/вставки из Word Document. Документ Word использует Smart Quotes. Вы можете заменить его специальным символом (& rsquo;) или просто ввести свой HTML-редактор (').
Я уверен, что это решит вашу проблему.
То же самое случилось со мной с символом "-" (длинный знак минус).
Я использовал эту простую замену, так что разрешите ее:
htmlText = htmlText.Replace('–', '-');
Вместо знака фунта я использовал: и фунт; без пространства. Это разрешило эту проблему для меня.
Для евро: евро; без пробела.