UTF-8 到 Unicode 代码点

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

是否有一个函数可以将 UTF-8 更改为 Unicode,将非特殊字符保留为普通字母和数字?

即德语单词“tchüß”将被渲染为“tch AC AC”(请注意,我正在编写 Unicode 代码)。

编辑:我正在尝试以下函数,但是虽然这个函数适用于 ASCII 32-127,但对于双字节字符似乎失败:

function strToHex ($string)
{
    $hex = '';
    for ($i = 0; $i < mb_strlen ($string, "utf-8"); $i++)
    {
        $id = ord (mb_substr ($string, $i, 1, "utf-8"));
        $hex .= ($id <= 128) ? mb_substr ($string, $i, 1, "utf-8") : "&#" . $id . ";";
}

    return ($hex);
}

有什么想法吗?

编辑2:找到解决方案:PHP ord() 函数不适用于双字节字符。使用:http://nl.php.net/manual/en/function.ord.php#78032

php unicode utf-8
9个回答
28
投票

对于可读的形式,我会使用 JSON。 JSON 中不需要转义非 ASCII 字符,但 PHP 会这样做:

echo json_encode("tchüß");

"tch\u00fc\u00df"

11
投票

在 PHP 7 中,有一个新的 IntlChar::ord() 用于从给定的 UTF-8 字符查找 Unicode 代码点:

var_dump(sprintf('U+%04X', IntlChar::ord('ß')));

# Outputs: string(6) "U+00DF"

10
投票

对于想要查找任何字符的 Unicode 代码点的人来说,这可能很有用。然后,您可以将字符串编码为您想要的任何内容,用转义码替换某些字符,并将其他字符保留为二进制形式(例如 ascii 可打印字符),具体取决于您要使用它的上下文。

来自:将代码点映射到 Unicode 编码形式

UTF-32 的映射本质上是恒等映射: 用于对代码点进行编码的 32 位代码单元具有相同的整数值 作为代码点本身。

/**
 * Convert a string into an array of decimal Unicode code points.
 *
 * @param $string   [string] The string to convert to codepoints
 * @param $encoding [string] The encoding of $string
 * 
 * @return [array] Array of decimal codepoints for every character of $string
 */
function toCodePoint( $string, $encoding )
{
    $utf32  = mb_convert_encoding( $string, 'UTF-32', $encoding );
    $length = mb_strlen( $utf32, 'UTF-32' );
    $result = [];


    for( $i = 0; $i < $length; ++$i )

        $result[] = hexdec( bin2hex( mb_substr( $utf32, $i, 1, 'UTF-32' ) ) );


    return $result;
}

3
投票

可以使用 iconv 将一种字符集转换为另一种字符集:

http://php.net/manual/en/function.iconv.php

请注意,UTF 已经是 Unicode 编码。

另一种方法是简单地使用具有正确字符集的 htmlentities:

http://php.net/manual/en/function.htmlentities.php


2
投票

我猜你会在网站上打印出你的字符串?

我将所有数据库存储在 uft8 中,在输出之前使用 html_entities($string) 。

也许你必须尝试一下 html_entities(utf8_encode($string));


2
投票

我曾经创建了一个名为 _convert() 的函数,它将所有内容安全地编码为 UTF-8。


2
投票

在 php 5.6 上测试

/**
 * @param string $utf8char
 * @return string
 */
function toUnicodeCodePoint($utf8char)
{
    return 'U+' . dechex(mb_ord($utf8char));
}

/**
 * @see https://github.com/symfony/polyfill-mbstring
 * @param string $s
 * @return int
 */
function mb_ord($s)
{
    $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0;
    if (0xF0 <= $code) {
        return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80;
    }
    if (0xE0 <= $code) {
        return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80;
    }
    if (0xC0 <= $code) {
        return (($code - 0xC0) << 6) + $s[2] - 0x80;
    }

    return $code;
}

echo toUnicodeCodePoint('😓');
// U+1f613

0
投票

当我需要将西里尔语字符串(默认为 utf-8)转换为部分实体时,我遇到了问题 - 仅西里尔语。 最后我需要得到类似 JSON 的结果,如下所示:

<li class="my_class">City - Mocsow (Москва)</li>

对此:

<li class=\"my_class\">City - Mocsow (\u041c\u043e\u0441\u043a\u0432\u0430)<\/li>

所以,我有一个复杂的(主题作者和 Nus 的混合)解决方案:

function strToHex($string){
    $enc="utf-8";
    $hex = '';
    for ($i = 0; $i < mb_strlen ($string, $enc); $i++){
        $id = ord (mb_substr ($string, $i, 1, $enc));
        $hex .= ($id <= 128) ? mb_substr ($string, $i, 1, $enc) : toCodePoint(mb_substr ($string, $i, 1, $enc), $enc);
    }
    return $hex;
}
function toCodePoint($string, $encoding){
    $utf32  = mb_convert_encoding( $string, 'UTF-32', $encoding );
    $length = mb_strlen( $utf32, 'UTF-32' );
    $result = Array();
    for( $i = 0; $i < $length; ++$i )$result[] = "\u".substr(bin2hex( mb_substr( $utf32, $i, 1, 'UTF-32' ) ), 4,8);
    return implode("", $result);
}
$output=strToHex(
    str_replace( // this is for json compatible
        array("\"", "\n", "\r", "\t", "/"),
        array('\"', '\n', "", " ", "\/"),
        $text
    )
);
echo $output;

它在 php 5.2.17 上进行了测试:)


0
投票

我看到很多人混淆了 UTF-8、UTF-16...“编码”和 UNICODE 本身,即具有重叠 255 的大整数“ord”值的字符范围(并且需要使用 UTF-8 或 UTF-16 进行编码才能正确显示为字符)

这里有一个明确的例子来修正这些概念:

数值(整数/长整型)

129429
以十六进制表示为
0x1f995
然后,该值(以 unicode 形式呈现恐龙)将转换为:

\uD83E\uDD95
如果是 使用 UTF-16 编码
0xf09fa695
如果是 使用 UTF-8 编码

所以... UNICODE 不是 UTF-8 也不是 UTF-16。
这是 Unicode 值的两种“编码方案”。

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