PHP字符串中的Unicode字符

Tel*_*avo 147 php unicode

这个问题看起来很简单,但我找不到答案.

什么是PHP相当于以下C#代码行?

string str = "\u1000";
Run Code Online (Sandbox Code Playgroud)

此示例创建一个带有单个Unicode字符的字符串,其"Unicode数值"为十六进制的1000(十进制为4096).

也就是说,在PHP中,如何创建一个具有单个Unicode字符的字符串,其"Unicode数值"是已知的?

Ste*_*rig 165

因为JSON直接支持\uxxxx语法,所以我想到的第一件事就是:

$unicodeChar = '\u1000';
echo json_decode('"'.$unicodeChar.'"');
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用 mb_convert_encoding()

echo mb_convert_encoding('က', 'UTF-8', 'HTML-ENTITIES');
Run Code Online (Sandbox Code Playgroud)

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

echo mb_convert_encoding("\x10\x00", 'UTF-8', 'UTF-16BE');
Run Code Online (Sandbox Code Playgroud)

  • JSON不是JavaScript. (7认同)
  • @Gumbo:我知道,但这里没有任何区别.Javascript和JSON都支持`\ uxxxx` Unicode语法,因此您可以使用`json_decode`来处理人工创建的JSON字符串表示.我改变了措辞,但澄清了. (4认同)
  • 你需要`echo json_decode('"\ u201B"');`.unicode符号周围的双引号是必需的. (4认同)
  • 好的,所以对我的问题的一个答案的严格表述是:$ str = json_decode('"\ u1000"'); 谢谢. (2认同)

Bla*_*ole 128

PHP 7.0.0引入了"Unicode codepoint escape"语法.

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

$unicodeChar = "\u{1000}";
Run Code Online (Sandbox Code Playgroud)

  • 我相信OP需要这个答案,而不是被接受的答案。无论如何,当我搜索“ PHP中的Unicode”时,是因为我想要这个答案,而不是被接受的答案。首次提出此问题时,也许“ \ u {abcd}”不存在。如果是这样,现在应该移动接受的答案。 (2认同)

Gum*_*mbo 20

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);
}
Run Code Online (Sandbox Code Playgroud)

或者使用匿名函数表达式而不是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);
}
Run Code Online (Sandbox Code Playgroud)

它的用法:

$str = unicodeString("\u1000");
Run Code Online (Sandbox Code Playgroud)


Pac*_*ier 20

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

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

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

ASCII示例:

<?php
    echo("\x48\x65\x6C\x6C\x6F\x20\x57\x6F\x72\x6C\x64\x21");
?>
Run Code Online (Sandbox Code Playgroud)

你好,世界!

所以对于你的情况,你需要做的就是$str = "\x30\xA2";.但这些是字节,而不是字符.Unicode代码点的字节表示与UTF-16大端重合,因此我们可以直接将其打印出来:

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

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

UTF-16小端实例:

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

UTF-8示例:

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

还有pack功能,但你可以期待它很慢.


flo*_*ori 9

html_entity_decode('&#x30a8;', 0, 'UTF-8');
Run Code Online (Sandbox Code Playgroud)

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


Ham*_*raz 7

尝试便携式UTF-8:

$str = utf8_chr( 0x1000 );
$str = utf8_chr( '\u1000' );
$str = utf8_chr( 4096 );
Run Code Online (Sandbox Code Playgroud)

所有工作都完全一样.您可以使用获取角色的代码点utf8_ord().了解有关Portable UTF-8的更多信息.


Tim*_*hof 5

正如其他人提到的,PHP 7 引入了对\\uUnicode 语法的本机支持,从而使这个问题变得过时。

\n

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

\n

PHP 5 支持另一种选项:您可以使用二进制转义直接在 PHP 中对字符进行编码\\x

\n

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

\n

首先,一个证明:

\n
// Unicode Character 'HAIR SPACE' (U+200A)\n// Other way:\n$htmlEntityChar = "&#8202;";\n$realChar = html_entity_decode($htmlEntityChar);\n// My way:\n$phpChar = "\\xE2\\x80\\x8A";\necho 'Proof: ';\nvar_dump($realChar === $phpChar); // bool(true)\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

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

\n

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

\n
/** @author Krinkle 2018 */\nfunction str_encode_utf8binary($str) {\n    $output = '';\n    foreach (str_split($str) as $octet) {\n        $ordInt = ord($octet);\n        // Convert from int (base 10) to hex (base 16)\n        $ordHex = base_convert($ordInt, 10, 16);\n        $output .= '\\x' . $ordHex;\n    }\n    return $output;\n}\n\n// Example from literal string:\n// Unicode Character 'INFINITY' (U+221E)\necho str_encode_utf8binary('\xe2\x88\x9e') . "\\n";\n// \\xe2\\x88\\x9e\n\nfunction str_convert_html_to_utf8binary($str) {\n    return str_encode_utf8binary(html_entity_decode($str));\n}\nfunction str_convert_json_to_utf8binary($str) {\n    return str_encode_utf8binary(json_decode($str));\n}\n\n// Example from HTML:\n// Unicode Character 'HAIR SPACE' (U+200A)\necho str_convert_html_to_utf8binary('&#8202;') . "\\n";\n// \\xe2\\x80\\x8a\n\n// Example from JSON:\n// Unicode Character 'HAIR SPACE' (U+200A)\necho str_convert_json_to_utf8binary('"\\u200a"') . "\\n";\n// \\xe2\\x80\\x8a\n
Run Code Online (Sandbox Code Playgroud)\n