如果没有不成对的代理字符,我如何将表情符号等字符编码为UTF8? [英] How can I encode characters like emojis as UTF8 without unpaired surrogate characters?

查看:33
本文介绍了如果没有不成对的代理字符,我如何将表情符号等字符编码为UTF8?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有包含各种字符的字符串,需要写入Google BigQuery,它需要严格的UTF8字符串。在尝试使用各种表情符号输入编写字符串时,我收到错误:

java.lang.IllegalArgumentException: Unpaired surrogate at index 3373
    at org.apache.beam.sdk.repackaged.com.google.common.base.Utf8.encodedLengthGeneral(Utf8.java:93)
    at org.apache.beam.sdk.repackaged.com.google.common.base.Utf8.encodedLength(Utf8.java:67)
    at org.apache.beam.sdk.coders.StringUtf8Coder.getEncodedElementByteSize(StringUtf8Coder.java:145)
...

我有一个解决此问题的方法,只需从字符串中删除所有代理项字符:

    private static String removeSurrogates(String query) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < query.length(); i++) {
            char c = query.charAt(i);
            if (!(Character.isHighSurrogate(c) || Character.isLowSurrogate(c))) {
                sb.append(c);
            }
        }
        return sb.toString();
    }

但是,这会产生一个类似

的字符串

🍍🥔🍵🍵🏺🎧🎚🎙⚔⌨🎳⛳🏓🌏🏝🏝🕘🕒🕢🕠🎵🔇🎸🗓🔏⛏🔒

减少到只有四个表情符号

⚔⌨⛳⛏

是否有合适的方法将这些字符转换为UTF8而不丢失,并且不使用未配对的代理?

(对不起,我对字符集的总体理解不是很好)

推荐答案

我找到了问题。我们使用org.apache.commons.lang3.StringEscapeUtils.unescapeHtml4将字符串中的Html实体转换为它们的非编码形式。这似乎破坏了一些非拉丁字符。例如,通过此方法传递字符串"Italien🇮🇹"会将其转换为"Italien🇮?"(最后一个字符损坏)

通过此方法传递"🍍🥔🍵🍵🏺🎧🎚🎙⚔⌨🎳⛳🏓🌏🏝🏝🕘🕒🕢🕠🎵🔇🎸🗓🔏⛏🔒"会将其转换为"🍍?🥔?🍵?🍵?🏺?🎧?🎚?🎙?⚔⌨🎳?⛳🏓?🌏?🏝?"

import org.apache.commons.lang3.StringEscapeUtils;

public class CharacterTest {
    public static void main(String[] args) {
        String good = "🍍🥔🍵🍵🏺🎧🎚🎙⚔⌨🎳⛳🏓🌏🏝🏝🕘🕒🕢🕠🎵🔇🎸🗓🔏⛏🔒";
        String bad = StringEscapeUtils.unescapeHtml4(good);
        System.out.println(good + "->" + bad);
    }
}

🍍🥔🍵🍵🏺🎧🎚🎙⚔⌨🎳⛳🏓🌏🏝🏝🕘🕒🕢🕠🎵🔇🎸🗓🔏⛏🔒->🍍?🥔?🍵?🍵?🏺?🎧?🎚?🎙?⚔⌨🎳?⛳🏓?🌏?🏝?

立即查找替代的HTML实体解码器...

这篇关于如果没有不成对的代理字符,我如何将表情符号等字符编码为UTF8?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆