PHP 字符串中的 Unicode字符

这个问题看起来简单得令人尴尬,但我还没有找到答案。

什么是 PHP 等价于下面的 C # 代码行?

string str = "\u1000";

此示例创建一个字符串,其中只有一个 Unicode字符,其“ Unicode 数值”为十六进制的 1000(十进制的 4096)。

也就是说,在 PHP 中,如何创建一个只有一个“ Unicode 数值”已知的 Unicode字符的字符串?

252910 次浏览

因为 JSON 直接支持 \uxxxx语法,我首先想到的是:

$unicodeChar = '\u1000';
echo json_decode('"'.$unicodeChar.'"');

另一种选择是使用 mb_convert_encoding()

echo mb_convert_encoding('က', 'UTF-8', 'HTML-ENTITIES');

或者使用 UTF-16BE (big endian)和 Unicode 代码点之间的直接映射:

echo mb_convert_encoding("\x10\x00", 'UTF-8', 'UTF-16BE');

PHP 不知道这些 Unicode 转义序列。但是,由于未知的转义序列不受影响,您可以编写自己的函数来转换这样的 Unicode 转义序列:

function unicodeString($str, $encoding=null) {
if (is_null($encoding)) $encoding = ini_get('mbstring.internal_encoding');
return preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/u', create_function('$match', 'return mb_convert_encoding(pack("H*", $match[1]), '.var_export($encoding, true).', "UTF-16BE");'), $str);
}

或者用 匿名函数表达式匿名函数表达式代替 create_function:

function unicodeString($str, $encoding=null) {
if (is_null($encoding)) $encoding = ini_get('mbstring.internal_encoding');
return preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/u', function($match) use ($encoding) {
return mb_convert_encoding(pack('H*', $match[1]), $encoding, 'UTF-16BE');
}, $str);
}

用法:

$str = unicodeString("\u1000");
html_entity_decode('エ', 0, 'UTF-8');

但是 json _ decode ()解决方案要快得多(大约50倍)。

试试 便携式 UTF-8:

$str = utf8_chr( 0x1000 );
$str = utf8_chr( '\u1000' );
$str = utf8_chr( 4096 );

所有工作完全相同的方式。你可以得到一个字符的代码与 utf8_ord().了解更多关于便携式 UTF-8的信息

我想知道为什么还没有人提到这一点,但是你可以在 双引号字符串双引号字符串中使用转义序列做一个几乎相同的版本:

\x[0-9A-Fa-f]{1,2}

与正则表达式匹配的字符序列是 十六进制表示法的字符。

ASCII 示例:

<?php
echo("\x48\x65\x6C\x6C\x6F\x20\x57\x6F\x72\x6C\x64\x21");
?>

你好,世界!

因此,对于您的情况,所有您需要做的是 $str = "\x30\xA2";。但这些是 字节,不是字符。Unicode 代码点的字节表示符合 UTF-16 big endian,因此我们可以直接打印出来:

<?php
header('content-type:text/html;charset=utf-16be');
echo("\x30\xA2");
?>

失效

如果使用不同的编码,则需要相应地修改字节(大多数情况下使用库完成,但也可以手工完成)。

UTF-16 little endian 示例:

<?php
header('content-type:text/html;charset=utf-16le');
echo("\xA2\x30");
?>

失效

UTF-8例子:

<?php
header('content-type:text/html;charset=utf-8');
echo("\xE3\x82\xA2");
?>

失效

还有 pack函数,但是可以预期它会很慢。

PHP 7.0.0引入了 “ Unicode 代码点转义”语法

现在可以使用 双引号Herdoc字符串轻松编写 Unicode 字符,而不需要调用任何函数。

$unicodeChar = "\u{1000}";

正如其他人所提到的,PHP7直接引入了对 \u Unicode 语法的支持。

正如其他人提到的那样,从 PHP 中任何合理的 Unicode字符描述中获得字符串值的唯一方法是从其他形式(如 JSON 解析、 HTML 解析或其他形式)转换它。但这是以运行时性能成本为代价的。

不过,还有一个选择。您可以使用 \x二进制转义在 PHP 中直接对字符进行编码。\x转义语法也是 PHP5支持

如果您不希望通过字符串的自然形式直接在字符串中输入字符,那么这种方法尤其有用。例如,如果它是一个不可见的控制字符,或者其他难以检测到的空格。

首先,举个例子:

// Unicode Character 'HAIR SPACE' (U+200A)
$htmlEntityChar = "&#8202;";
$realChar = html_entity_decode($htmlEntityChar);
$phpChar = "\xE2\x80\x8A";
echo 'Proof: ';
var_dump($realChar === $phpChar); // bool(true)

注意,正如 Pacerier 在另一个答案中提到的,这个二进制代码对于特定的字符编码是唯一的。在上面的示例中,\xE2\x80\x8A是用 UTF-8表示 U + 200A 的二进制编码。

下一个问题是,如何从 U+200A\xE2\x80\x8A

下面是一个 PHP 脚本,用于基于 JSON 字符串、 HTML 实体或任何其他方法(一旦将其作为本机字符串)为任何字符生成转义序列。

function str_encode_utf8binary($str) {
/** @author Krinkle 2018 */
$output = '';
foreach (str_split($str) as $octet) {
$ordInt = ord($octet);
// Convert from int (base 10) to hex (base 16), for PHP \x syntax
$ordHex = base_convert($ordInt, 10, 16);
$output .= '\x' . $ordHex;
}
return $output;
}


function str_convert_html_to_utf8binary($str) {
return str_encode_utf8binary(html_entity_decode($str));
}
function str_convert_json_to_utf8binary($str) {
return str_encode_utf8binary(json_decode($str));
}


// Example for raw string: Unicode Character 'INFINITY' (U+221E)
echo str_encode_utf8binary('∞') . "\n";
// \xe2\x88\x9e


// Example for HTML: Unicode Character 'HAIR SPACE' (U+200A)
echo str_convert_html_to_utf8binary('&#8202;') . "\n";
// \xe2\x80\x8a


// Example for JSON: Unicode Character 'HAIR SPACE' (U+200A)
echo str_convert_json_to_utf8binary('"\u200a"') . "\n";
// \xe2\x80\x8a
function unicode_to_textstring($str){


$rawstr = pack('H*', $str);


$newstr =  iconv('UTF-16BE', 'UTF-8', $rawstr);
return $newstr;
}

$msg =’67714eac99c500200054006f006b0079006f002000530074006100740069006f006e003a0020’;

Echo unicode _ to _ textstring ($str) ;