【问题标题】:UTF-8 to Unicode Code PointsUTF-8 到 Unicode 代码点
【发布时间】:2011-08-18 11:12:10
【问题描述】:

是否有将 UTF-8 更改为 Unicode 将非特殊字符保留为普通字母和数字的功能?

即德语单词“tchüß”将呈现为“tch\20AC\21AC”之类的东西(请注意,我正在制作 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

【问题讨论】:

  • 将标题更改为更具描述性的名称 - UTF-8 Unicode。您可能正在寻找“UTF-8 到 Unicode 代码点”。
  • 一个有用的资源:@​​987654322@
  • 如何定义“非特殊字符”?
  • 不,您不能将 UTF-8 转换为 Unicode,除非是通过身份操作的病态情况。定义“无特殊字符”和“正常的字母和数字!像“%”和“/”这样的字符是特殊的吗?Control-C 呢?是什么使字母或数字正常或异常?ñ U+00F1 和 ð U+00F0 普通字母?什么是 ñ 真的是 n 后跟 U+0303?那么,是什么让字符成为字母或数字? ¼ U+00BC 和 ² U+00B2 不是数字吗?Unicode 6.0.0 有 100,520 个 GC=Letter 和 1,100 个 GC=Number 代码点,其中 456 个是 GC=Letter_Number 像 Ⅷ。(继续...)
  • Adrien:我永远不会想到这个定义。这意味着 Unicode 的 1,114,112 个代码点,其中只有 94 个是特殊字符,剩下 1,114,018 个被归类为“特殊字符”?这真是违反直觉。我声称发生频率低于其他数量五个数量级的那些是特殊的。否则,您就已经颠覆了特殊性的想法。从我的角度来看,实际上是代码点 32-126 是特殊的,而不是非特殊的。看不到将 99.99% 的东西称为“特殊”。正如我所说,我永远不会想到。

标签: php unicode utf-8


【解决方案1】:

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

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

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

【讨论】:

  • 请注意,您需要在 PHP.ini 中启用 extension=php_intl.dll 才能显示此类。
【解决方案2】:

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

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

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

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

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

【讨论】:

  • htmlentities 仅转换在 HTML 语言中定义了实体的字符,但它仅涵盖 Unicode 的一小部分。不幸的是,它不会为其他字符创建 &amp;#...; 字符引用。
  • 我知道,但iconv 往往会带来一些问题。并非所有字符似乎都能为每个字符集完美转换。这就是我提到htmlentities 函数的原因。在iconv功能页面的cmets中也有建议:nl.php.net/manual/en/function.iconv.php#81494
【解决方案3】:

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

echo json_encode("tchüß");

"tch\u00fc\u00df"

【讨论】:

  • 有意思,没想到这个!
  • 太棒了!像魅力一样工作.. :)
  • JSON 默认需要转义非 ASCII 字符。你应该每次都这样做。
  • 很好的解决方案!
  • @WilliamR,你为什么这么认为?根据定义,JSON 是 UTF-8,它完全支持 Unicode。不需要转义任何 Unicode。
【解决方案4】:

在 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

【讨论】:

    【解决方案5】:

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

    发件人:Mapping codepoints to Unicode encoding forms

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

    【讨论】:

    • 我需要获取 UTF-8 字符串的代码点值以检查给定的 TTF 字体是否支持它们,并且此函数可以完美地获取代码点值。
    【解决方案6】:

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

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

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

    【讨论】:

      【解决方案7】:

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

      【讨论】:

      • 您可以在此处添加答案,而不是作为链接。
      【解决方案8】:

      当我需要将带有西里尔文的字符串(默认为 utf-8)部分转换为实体时遇到问题 - 仅西里尔文。 最后我需要得到类似 JSON 的结果,像这样:

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

      到这里:

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

      所以,我有一个 compex(主题作者和 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 上测试过 :)

      【讨论】:

        猜你喜欢
        • 2017-06-20
        • 2014-10-27
        • 2021-10-20
        • 2015-12-06
        • 2012-06-20
        • 2013-03-23
        • 2014-06-24
        • 1970-01-01
        相关资源
        最近更新 更多