【问题标题】:Encode emoji to unicode code point - PHP/JS将表情符号编码为 un​​icode 代码点 - PHP/JS
【发布时间】:2015-09-16 00:34:20
【问题描述】:

假设我在 PHP 上有这个字符串:

$str = '????️';

或者 JavaScript 上的这个字符串:

var str = '????️';

如果我执行utf8_encode($str),结果是\ud83c\udc04\ufe0f,但我希望它是1F0041f004\u1f004,以便查找与该字符匹配的图像文件。

我做了很多在线搜索,寻找一种对其进行编码的方法,我发现有很多地方使用相同的术语来表示非常不同的事物,看起来我想要的是“编码”一个字符串到 UTF-32 代码点,但我真的不知道如何命名我想要的,我只想使用 PHP 和/或 JavaScript 将这个 ????️ 转换成这个 1f004

http://www.fileformat.info/info/unicode/char/1f004/index.htm

谢谢。

【问题讨论】:

    标签: javascript php unicode encoding


    【解决方案1】:

    您想从字节流中获取 unicode 代码点,因此 utf8_encode 无济于事。我找到了一个实现here

    function utf8_to_unicode($c)
    {
        $ord0 = ord($c{0}); if ($ord0>=0   && $ord0<=127) return $ord0;
        $ord1 = ord($c{1}); if ($ord0>=192 && $ord0<=223) return ($ord0-192)*64 + ($ord1-128);
        $ord2 = ord($c{2}); if ($ord0>=224 && $ord0<=239) return ($ord0-224)*4096 + ($ord1-128)*64 + ($ord2-128);
        $ord3 = ord($c{3}); if ($ord0>=240 && $ord0<=247) return ($ord0-240)*262144 + ($ord1-128)*4096 + ($ord2-128)*64 + ($ord3-128);
        return false;
    }
    
    var_dump( dechex(utf8_to_unicode('?️')) ); // string(5) "1f004"
    

    UTF-8 兼容单字节 ASCII 编码,所以$ord0 = ord($c{0}); if ($ord0&gt;=0 &amp;&amp; $ord0&lt;=127) return $ord0; 非常简单。大于 127 的代码点由多字节序列表示。接下来的 1,920 个字符需要两个字节进行编码,$ord1 = ord($c{1}); if ($ord0&gt;=192 &amp;&amp; $ord0&lt;=223) return ($ord0-192)*64 + ($ord1-128);。第一个字节需要介于 192 (11000000) 和 223 (11011111) 之间才能格式正确。第二个字节必须是 10xxxxxx(即十进制的 128 到 191)。这里表示的第一个码位是 U+0080,最后一个是 U+07FF。

    等等。

    【讨论】:

    • 非常感谢,我将把它移植到 JavaScript,你太棒了!
    • 你可以在 JS 中使用这个库:github.com/mathiasbynens/jsesc 并像这样运行:jsesc('?️', {'es6': true, 'escapeEverything': true});
    【解决方案2】:

    JavaScript 函数:

    function e2u(str){
        str = str.replace(/\ufe0f|\u200d/gm, ''); // strips unicode variation selector and zero-width joiner
        var i = 0, c = 0, p = 0, r = [];
        while (i < str.length){
            c = str.charCodeAt(i++);
            if (p){
                r.push((65536+(p-55296<<10)+(c-56320)).toString(16));
                p = 0;
            } else if (55296 <= c && c <= 56319){
                p = c;
            } else {
                r.push(c.toString(16));
            }
        }
        return r.join('-');
    }
    

    【讨论】:

      猜你喜欢
      • 2014-03-13
      • 1970-01-01
      • 2016-08-21
      • 1970-01-01
      • 1970-01-01
      • 2021-11-25
      • 2018-01-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多