【问题标题】:How to convert UTF16 surrogate pairs to equivalent HEX codepoint in PHP?如何在 PHP 中将 UTF16 代理对转换为等效的 HEX 代码点?
【发布时间】:2017-01-06 16:27:12
【问题描述】:

我正在制作一个应用程序,聊天将从 iOS 应用发送,但管理员可以从 PHP 内置的管理面板查看聊天。

从 DB,我会收到这样的聊天消息:

Hi, Jax\ud83d\ude1b\ud83d\ude44! can we go for a coffee?

我正在使用 twemoji library 可以将 HEX 代码点转换为图像。

我们详细说一下,

在 php 部分,我有以下代码:-

$text = "This is fun \u1f602! \u1f1e8 ";
$html = preg_replace("/\\\\u([0-9A-F]{2,5})/i", "&#x$1;", $text);
echo $html;

现在,twemoji 解析 HTML 文档的整个正文以将 Hex 代码点替换为图像。

window.onload = function() {

  // Set the size of the rendered Emojis
  // This can be set to 16x16, 36x36, or 72x72
  twemoji.size = '16x16';

  // Parse the document body and
  // insert <img> tags in place of Unicode Emojis
  twemoji.parse(document.body);
}

所以,我需要将所有 UTF-16 替换为 HEX 代码点的文本(对于表情符号)。 我该怎么做?

【问题讨论】:

    标签: php utf-16 codepoint


    【解决方案1】:

    这里有一个双重问题:

    • 检测到存在编码的代理对
    • 实际上将该代理项对转换为 HTML 实体

    解释问题的复杂性远远超出了单个答案的范围(您必须为此阅读 UTF-16),但此代码片段似乎可以解决您的问题:

    $text = "Hi, Jax\\ud83d\\ude1b\\ud83d\\ude44! can we go for a coffee?";
    
    $result = preg_replace_callback('/\\\\u(d[89ab][0-9a-f]{2})\\\\u(d[c-f][0-9a-f]{2})/i', function ($matches) {
        $first = $matches[1];
        $second = $matches[2];
        $value = ((eval("return 0x$first;") & 0x3ff) << 10) | (eval("return 0x$second;") & 0x3ff);
        $value += 0x10000;
        return "&#$value;";
      }, $text);
    
    echo $result;
    

    我知道几乎总是不鼓励使用eval,但由于正则表达式匹配(您知道匹配只包含十六进制数字),在此示例中它是完全安全的。

    【讨论】:

    • 这绝对是个魅力十足的男人......但是有些配对并没有得到转换。
    • 什么配对?您确定它们是实际的对而不是 BMP 代码点(将简单地编码为\uNNNN,使用一个转义序列而不是两个)?如果是这种情况,您需要使用另一个正则表达式替换来过滤掉它们。这非常简单,因为您只是想用&amp;#xNNNN; 替换\uNNNN(其中NNNN 正好是四个十六进制数字),并且可以通过简单的正则表达式替换来完成。
    • 点赞\ud83d\ude43
    猜你喜欢
    • 2017-08-05
    • 2011-12-05
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    • 2015-11-02
    • 2015-10-08
    • 1970-01-01
    相关资源
    最近更新 更多