Как преобразовать текстовый блок Unicode в кодовую точку UTF-8 (HEX)?
У меня есть текстовый блок Unicode, например:
ụ
ư
ứ
Ỳ
Ỷ
Ỵ
Đ
Теперь я хочу преобразовать этот оригинальный текстовый блок Unicode в текстовый блок кодовой точки UTF-8 (HEX) (см. столбец шестнадцатеричный UTF-8 на этой странице: https://en.wikipedia.org/wiki/UTF-8), PHP
; например:
\xe1\xbb\xa5
\xc6\xb0
\xe1\xbb\xa9
\xe1\xbb\xb2
\xe1\xbb\xb6
\xe1\xbb\xb4
\xc4\x90
Не:
0x1EE5
0x01B0
0x1EE9
0x1EF2
0x1EF6
0x1EF4
0x0110
Есть ли способ сделать это, PHP?
Я прочитал эту тему (PHP: конвертировать кодовую точку юникода в UTF-8). Но он не похож на мой вопрос.
Извините, я мало что знаю о Unicode
.
Ответы
Ответ 1
Я думаю, что вы ищете функцию bin2hex():
Преобразование двоичных данных в шестнадцатеричное представление
И форматируйте, добавив \x
к каждому байту (00-FF)
function str_hex_format ($bin) {
return '\x'.implode('\x', str_split(bin2hex($bin), 2));
}
Для вашего образца:
// utf8 encoded input
$arr = ["ụ","ư","ứ","Ỳ","Ỷ","Ỵ","Đ"];
foreach($arr AS $v)
echo $v . " => " . str_hex_format($v) . "\n";
Смотрите тест на eval.in (истекает срок действия ссылки)
ụ => \xe1\xbb\xa5
ư => \xc6\xb0
ứ => \xe1\xbb\xa9
Ỳ => \xe1\xbb\xb2
Ỷ => \xe1\xbb\xb6
Ỵ => \xe1\xbb\xb4
Đ => \xc4\x90
Пример декодирования: $str = str_hex_format("ụưứỲỶỴĐ"); echo $str;
\ xe1\Xbb\xa5\xc6\XB0\xe1\Xbb\xA9\xe1\Xbb\XB2\xe1\Xbb\XB6\xe1\Xbb\XB4\XC4\x90
echo hex2bin(str_replace('\x', "", $str));
ụưứỲỶỴĐ
Подробнее о escape-последовательности \x
в двойных кавычках см. руководство по php.
Ответ 2
PHP обрабатывает строки как массивы символов, независимо от кодировки. Если вам не нужно разграничивать символы UTF8, то работает что-то вроде этого:
$str='ụưứỲỶỴĐ';
foreach(str_split($str) as $char)
echo '\x'.str_pad(dechex(ord($char)),'0',2,STR_PAD_LEFT);
Вывод:
\xe1\xbb\xa5\xc6\xb0\xe1\xbb\xa9\xe1\xbb\xb2\xe1\xbb\xb6\xe1\xbb\xb4\xc4\x90
Если вам нужно разграничить символы UTF8 (т.е. с новой строкой), вам понадобится что-то вроде этого:
$str='ụưứỲỶỴĐ';
foreach(array_slice(preg_split('~~u',$str),1,-1) as $UTF8char){ // split before/after every UTF8 character and remove first/last empty string
foreach(str_split($UTF8char) as $char)
echo '\x'.str_pad(dechex(ord($char)),'0',2,STR_PAD_LEFT);
echo "\n"; // delimiter
}
Вывод:
\xe1\xbb\xa5
\xc6\xb0
\xe1\xbb\xa9
\xe1\xbb\xb2
\xe1\xbb\xb6
\xe1\xbb\xb4
\xc4\x90
Это разделяет строку на символы UTF8 с помощью preg_split
и u
. Поскольку preg_split
возвращает пустую строку перед первым символом и пустую строку после последнего символа, нам нужно array_slice
первый и последний символы. Это может быть легко изменено для возврата массива, например.
Edit:
Более "правильный" способ сделать это:
echo trim(json_encode(utf8_encode('ụưứỲỶỴĐ')),'"');
Ответ 3
Главное, что вам нужно сделать, - сказать PHP правильно интерпретировать входящие символы Юникода. После этого вы можете преобразовать их в UTF-8, а затем, при необходимости, в шестнадцатеричном формате.
Этот фрагмент кода принимает ваш примерный символ в Unicode, преобразует его в UTF-8 и затем сбрасывает шестнадцатеричное представление этих символов.
<?php
// Hex equivalent of "ụưứỲỶỴĐ" in Unicode
$unistr = "\x1E\xE5\x01\xB0\x1E\xE9\x1E\xF2\x1E\xF6\x1E\xF4\x01\x10";
echo " length=" . mb_strlen($unistr, 'UCS-2BE') . "\n";
// Here the key statement, convert from Unicode 16-bit to UTF-8
$utf8str = mb_convert_encoding($unistr, "UTF-8", 'UCS-2BE');
echo $utf8str . "\n";
for($i=0; $i < mb_strlen($utf8str, 'UTF-8'); $i++) {
$c = mb_substr($utf8str, $i, 1, 'UTF-8');
$hex = bin2hex($c);
echo $c . "\t" . $hex . "\t" . preg_replace("/([0-9a-f]{2})/", '\\\\x\\1', $hex) . "\n";
}
?>
Выдает
length=7
ụưứỲỶỴĐ
ụ e1bba5 \xe1\xbb\xa5
ư c6b0 \xc6\xb0
ứ e1bba9 \xe1\xbb\xa9
Ỳ e1bbb2 \xe1\xbb\xb2
Ỷ e1bbb6 \xe1\xbb\xb6
Ỵ e1bbb4 \xe1\xbb\xb4
Đ c490 \xc4\x90