Как я могу преобразовать ссылки на символы HTML (& # X5E3;) для регулярного UTF-8?
-
01-10-2019 - |
Вопрос
У меня есть несколько веб-сайтов иврите, которые содержат ссылки на символы, такие как: נוף
Я могу просмотреть только эти буквы, если я сохраню файл как .html и просмотреть в кодировке UTF-8.
Если я попытаюсь открыть его как обычный текстовый файл, то кодировка UTF-8 не отображает правильный выход.
Я заметил, что если я открою текстовый редактор и пишу иврит в UTF-8, каждый персонаж принимает два байта не 4 байт линии в этом примере (ו
)
Любые идеи, если это UTF-16 или любой другой вид представления писем UTF?
Как я могу преобразовать его на обычные буквы, если это возможно?
Используя последнюю версию PHP.
Решение
Это ссылки на символы которые относятся к характеру в ISO 10646, указав кодовую точку этого персонажа в десятичном периоде (&#N.;
) или шестнадцатеричный (&#xN.;
) Обозначение.
Вы можете использовать html_entity_decode
это декодирует такие ссылки на характеристики, а также ссылки на объекты для Сущности, определенные для HTML 4, поэтому другие ссылки любят <
, >
, &
Также будет декодировать:
$str = html_entity_decode($str, ENT_NOQUOTES, 'UTF-8');
Если вы просто хотите декодировать числовые ссылки на символы, вы можете использовать это:
function html_dereference($match) {
if (strtolower($match[1][0]) === 'x') {
$codepoint = intval(substr($match[1], 1), 16);
} else {
$codepoint = intval($match[1], 10);
}
return mb_convert_encoding(pack('N', $codepoint), 'UTF-8', 'UTF-32BE');
}
$str = preg_replace_callback('/&#(x[0-9a-f]+|[0-9]+);/i', 'html_dereference', $str);
Так как Юриколовский а также Thirtydot. указал в Другой вопрос, Похоже, что поставщики браузера «молча» договорились о том, что о чем-то, что касается картирования характере, которые отличаются от спецификации и совершенно незаменим.
Кажется, что некоторые характеристики персонажей, которые обычно будут сопоставлены на Латинская 1 Дополнение Но это на самом деле отображается на разных персонажах. Это связано сопоставление, которое предположило бы, что предположим отображение символов из Windows-1252 вместо ISO 8859-1, на котором набор символов Unicode настроен. Jukka Korpela написала Обширная статья по этой теме.
Теперь вот расширение функции, упомянутой выше, которая обрабатывает эту quirk:
function html_character_reference_decode($string, $encoding='UTF-8', $fixMappingBug=true) {
$deref = function($match) use ($encoding, $fixMappingBug) {
if (strtolower($match[1][0]) === "x") {
$codepoint = intval(substr($match[1], 1), 16);
} else {
$codepoint = intval($match[1], 10);
}
// @see http://www.cs.tut.fi/~jkorpela/www/windows-chars.html
if ($fixMappingBug && $codepoint >= 130 && $codepoint <= 159) {
$mapping = array(
8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352, 8249,
338, 141, 142, 143, 144, 8216, 8217, 8220, 8221, 8226,
8211, 8212, 732, 8482, 353, 8250, 339, 157, 158, 376);
$codepoint = $mapping[$codepoint-130];
}
return mb_convert_encoding(pack("N", $codepoint), $encoding, "UTF-32BE");
};
return preg_replace_callback('/&#(x[0-9a-f]+|[0-9]+);/i', $deref, $string);
}
Если анонимные функции недоступны (введены с 5.3.0), вы также можете использовать create_function
:
$deref = create_function('$match', '
$encoding = '.var_export($encoding, true).';
$fixMappingBug = '.var_export($fixMappingBug, true).';
if (strtolower($match[1][0]) === "x") {
$codepoint = intval(substr($match[1], 1), 16);
} else {
$codepoint = intval($match[1], 10);
}
// @see http://www.cs.tut.fi/~jkorpela/www/windows-chars.html
if ($fixMappingBug && $codepoint >= 130 && $codepoint <= 159) {
$mapping = array(
8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352, 8249,
338, 141, 142, 143, 144, 8216, 8217, 8220, 8221, 8226,
8211, 8212, 732, 8482, 353, 8250, 339, 157, 158, 376);
$codepoint = $mapping[$codepoint-130];
}
return mb_convert_encoding(pack("N", $codepoint), $encoding, "UTF-32BE");
');
Вот еще одна функция, которая пытается соблюдать Поведение HTML 5:
function html5_decode($string, $flags=ENT_COMPAT, $charset='UTF-8') {
$deref = function($match) use ($flags, $charset) {
if ($match[1][0] === '#') {
if (strtolower($match[1][0]) === '#') {
$codepoint = intval(substr($match[1], 2), 16);
} else {
$codepoint = intval(substr($match[1], 1), 10);
}
// HTML 5 specific behavior
// @see http://dev.w3.org/html5/spec/tokenization.html#tokenizing-character-references
// handle Windows-1252 mismapping
// @see http://www.cs.tut.fi/~jkorpela/www/windows-chars.html
// @see http://dev.w3.org/html5/spec/tokenization.html#table-charref-overrides
$overrides = array(
0x00=>0xFFFD,0x80=>0x20AC,0x82=>0x201A,0x83=>0x0192,0x84=>0x201E,
0x85=>0x2026,0x86=>0x2020,0x87=>0x2021,0x88=>0x02C6,0x89=>0x2030,
0x8A=>0x0160,0x8B=>0x2039,0x8C=>0x0152,0x8E=>0x017D,0x91=>0x2018,
0x92=>0x2019,0x93=>0x201C,0x94=>0x201D,0x95=>0x2022,0x96=>0x2013,
0x97=>0x2014,0x98=>0x02DC,0x99=>0x2122,0x9A=>0x0161,0x9B=>0x203A,
0x9C=>0x0153,0x9E=>0x017E,0x9F=>0x0178);
if (isset($windows1252Mapping[$codepoint])) {
$codepoint = $windows1252Mapping[$codepoint];
}
if (($codepoint >= 0xD800 && $codepoint <= 0xDFFF) || $codepoint > 0x10FFFF) {
$codepoint = 0xFFFD;
}
if (($codepoint >= 0x0001 && $codepoint <= 0x0008) ||
($codepoint >= 0x000E && $codepoint <= 0x001F) ||
($codepoint >= 0x007F && $codepoint <= 0x009F) ||
($codepoint >= 0xFDD0 && $codepoint <= 0xFDEF) ||
in_array($codepoint, array(
0x000B, 0xFFFE, 0xFFFF, 0x1FFFE, 0x1FFFF, 0x2FFFE, 0x2FFFF,
0x3FFFE, 0x3FFFF, 0x4FFFE, 0x4FFFF, 0x5FFFE, 0x5FFFF, 0x6FFFE,
0x6FFFF, 0x7FFFE, 0x7FFFF, 0x8FFFE, 0x8FFFF, 0x9FFFE, 0x9FFFF,
0xAFFFE, 0xAFFFF, 0xBFFFE, 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE,
0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, 0xFFFFF, 0x10FFFE, 0x10FFFF))) {
$codepoint = 0xFFFD;
}
return mb_convert_encoding(pack("N", $codepoint), $charset, "UTF-32BE");
} else {
return html_entity_decode($match[0], $flags, $charset);
}
};
return preg_replace_callback('/&(#(?:x[0-9a-f]+|[0-9]+)|[A-Za-z0-9]+);/i', $deref, $string);
}
Я также заметил, что в PHP 5.4.0 html_entity_decode
функция был добавлен другой флаг имени Ent_html5. для поведения HTML 5.
Другие советы
Это XML Характеристика личностис. Вы хотите декодировать их, используя html_entity_decode()
:
$string = html_entity_decode($string, ENT_QUOTES, 'UTF-8');
Для получения дополнительной информации вы можете найти Google для рассматриваемого предприятия. Посмотрите эти несколько примеров: