如何将 Unicode 文本块转换为 UTF-8 (HEX) 代码点?

Posted

技术标签:

【中文标题】如何将 Unicode 文本块转换为 UTF-8 (HEX) 代码点?【英文标题】:How to convert a Unicode text-block to UTF-8 (HEX) code point? 【发布时间】:2015-10-08 16:52:19 【问题描述】:

我有一个 Unicode 文本块,如下所示:

ụ
ư
ứ
Ỳ
Ỷ
Ỵ
Đ

现在,我想将此原始 Unicode 文本块转换为 UTF-8 (HEX) 代码点的文本块(请参阅此页面上的 Hexadecimal UTF-8 列:@ 987654321@), 由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: Convert unicode codepoint to UTF-8)。但是,它与我的问题不相似


对不起,我对Unicode了解不多。

【问题讨论】:

您必须知道(或尝试猜测,但这仅在某些时候有效)您的输入采用什么编码。如果它已经是 UTF-8,那么它可能已经是您想要的格式-- 假设0xe1 不是指代表0xe1 的4 个字节,而是代表数字225 的一个字节。 second answer on the question you link to 确实将 Unicode 代码点转换为 UTF-8 字节。 你能展示你尝试过的东西吗?这样我们就可以确切地知道您要做什么。目前,有很多方法可以解释您的问题,因为我们正在尝试猜测您进行此类转换的目的。 【参考方案1】:

我想你正在寻找bin2hex() function:

将二进制数据转换为十六进制表示

并通过在每个字节前加上\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";

See test at 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));

ụưứỲỶỴĐ


有关转义序列的更多信息\x双引号字符串see php manual。

【讨论】:

+1。这正是我为 codepoints.net 所做的:github.com/Codepoints/Codepoints.net/blob/…【参考方案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

这使用preg_splitu 标志将字符串拆分为UTF8 字符。由于preg_split返回第一个字符之前的空字符串和最后一个字符之后的空字符串,所以我们需要array_slice第一个和最后一个字符。例如,这可以很容易地修改为返回一个数组。

编辑: 一个更“正确”的方法是:

echo trim(json_encode(utf8_encode('ụưứỲỶỴĐ')),'"');

【讨论】:

【参考方案3】:

您需要做的主要事情是告诉 PHP 正确解释传入的 Unicode 字符。完成此操作后,您可以将它们转换为 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's 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

【讨论】:

以上是关于如何将 Unicode 文本块转换为 UTF-8 (HEX) 代码点?的主要内容,如果未能解决你的问题,请参考以下文章

Python 2.7:如何将字符串中的 unicode 转义转换为实际的 utf-8 字符

将 Python 转义的 unicode 序列转换为 UTF-8

如何将表示 UTF-8 字符的 int 转换为 Unicode 代码点?

php - 如何将 unicode 转换为 utf-8 字符串

如何将 ANSI 文本转换为 Unicode?

如何将4字节utf-8的emoji表情转换为unicode字符编码