PHP字符串中的Unicode字符

时间:2011-05-19 12:09:34

标签: php unicode

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

与以下C#代码行等效的PHP是什么?

string str = "\u1000";

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

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

8 个答案:

答案 0 :(得分:162)

因为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');

答案 1 :(得分:117)

PHP 7.0.0引入了"Unicode codepoint escape" syntax

现在可以使用double-quotedheredoc字符串轻松编写Unicode字符,而无需调用任何函数。

$unicodeChar = "\u{1000}";

答案 2 :(得分:19)

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

或使用anonymous function expression代替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");

答案 3 :(得分:19)

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

  

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

     

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

ASCII示例:

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

Hello World!

因此,对于您的情况,您需要做的只是$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功能,但您可以预期它会很慢。

答案 4 :(得分:7)

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

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

答案 5 :(得分:7)

尝试Portable UTF-8

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

所有工作方式完全相同。您可以使用utf8_ord()获取角色的代码点。 Read more about Portable UTF-8

答案 6 :(得分:1)

正如其他人所说,PHP 7直接引入了对\u Unicode语法的支持。

正如其他人所提到的,从PHP中任何合理的Unicode字符描述中获取字符串值的唯一方法是将其转换为其他内容(例如JSON解析,HTML解析或其他形式)。但这是运行时性能成本。

但是,还有另一种选择。您可以使用\x二进制转义直接在PHP中对字符进行编码。 PHP 5中还支持{strong} \x转义语法。

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

首先,一个证据示例:

// 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

答案 7 :(得分:0)

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