从代码点输出 Unicode 字符

问题描述 投票:0回答:8

这个问题看起来简单得令人尴尬,但我一直找不到答案。

以下 C# 代码行对应的 PHP 是什么?

string str = "\u1000";

此示例创建一个包含单个 Unicode 字符的字符串,其“Unicode 数值”为十六进制的

1000
(十进制的
4096
)。

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

php unicode
8个回答
275
投票

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

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

$unicodeChar = "\u{1000}";

193
投票

因为 JSON 直接支持

\uxxxx
语法,我首先想到的是:

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

另一种选择是使用

mb_convert_encoding()

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

或利用 UTF-16BE(大端)和 Unicode 代码点之间的直接映射:

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

24
投票

我想知道为什么还没有人提到这一点,但是您可以在双引号字符串中使用转义序列来实现几乎等效的版本

\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 大端一致,因此我们可以直接打印出来:

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

如果您使用不同的编码,则需要相应地更改字节(主要通过库完成,但也可以手动完成)。

UTF-16 小端字节序示例:

<?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
功能,但你可以预料它会很慢。


23
投票

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");

11
投票
html_entity_decode('&#x30a8;', 0, 'UTF-8');

这也有效。然而 json_decode() 解决方案要快得多(大约 50 倍)。


6
投票

正如其他人提到的,PHP 7 引入了对

\u
Unicode 语法的本机支持,从而使这个问题变得过时。

正如其他人也提到的,对于 PHP 5,从 PHP 中的 Unicode 字符描述获取字符串值的最简单方法是将其从其他格式(例如 JSON 或 HTML 实体)转换。但是,这是以运行时性能为代价的。

还有另外一个选项,在 PHP 5 中受支持:您可以使用

\x
二进制转义直接在 PHP 中对字符进行编码。

如果您不想在字符串中输入字符作为文字,这尤其有用。例如,如果它是一个不可见的控制字符,或者空格(很难区分)。

首先,证明:

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

正如 Pacerier 在另一个答案中提到的,这个二进制代码对于特定的字符编码是唯一的。在上面的示例中,

\xE2\x80\x8A
是 U+200A 在 UTF-8 中的二进制编码。

下一个问题是,如何从

U+200A
\xE2\x80\x8A

下面的 PHP 脚本打印任何字符所需的转义序列。

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

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

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 from HTML:
// Unicode Character 'HAIR SPACE' (U+200A)
echo str_convert_html_to_utf8binary('&#8202;') . "\n";
// \xe2\x80\x8a

// Example from JSON:
// Unicode Character 'HAIR SPACE' (U+200A)
echo str_convert_json_to_utf8binary('"\u200a"') . "\n";
// \xe2\x80\x8a

5
投票

尝试便携式UTF-8

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

所有工作方式完全相同。您可以使用

utf8_ord()
获取字符的代码点。 了解有关便携式 UTF-8 的更多信息


0
投票
function unicode_to_textstring($str){

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

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

$msg = '67714eac99c500200054006f006b0079006f002000530074006100740069006f006e003a0020';

回显 unicode_to_textstring($str);

© www.soinside.com 2019 - 2024. All rights reserved.