如何在没有未配对代理字符的情况下将表情符号等字符编码为 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 而不会丢失,并且不使用不成对的代理?

(抱歉,我对一般字符集的理解不是很好)



慕容3067478
浏览 88回答 3
3回答

心有法竹

我发现了问题。我们正在使用 org.apache.commons.lang3.StringEscapeUtils.unescapeHtml4 将字符串中的 HTML 实体转换为它们的非编码形式。这似乎破坏了一些非拉丁字符。例如,通过此方法传递字符串“Italien 🇮🇹”会将其转换为“Italien 🇮?”&nbsp;(最后一个字符被破坏)通过此方法传递“🍍🥔🍵🍵🏺🎧🎚🎙⚔⌨🎳⛳🏓🌏🏝🏝🕘🕒🕢🕠🎵🔇🎸🗓🔏⛏🔒”将其转换为“🍍??🥔?🍵??🏺?🎧?🎚?🎚? ?🎙?⚔⌨🎳?⛳🏓?🌏?🏝?”import org.apache.commons.lang3.StringEscapeUtils;public class CharacterTest {&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; String good = "🍍🥔🍵🍵🏺🎧🎚🎙⚔⌨🎳⛳🏓🌏🏝🏝🕘🕒🕢🕠🎵🔇🎸🗓🔏⛏🔒";&nbsp; &nbsp; &nbsp; &nbsp; String bad = StringEscapeUtils.unescapeHtml4(good);&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(good + "->" + bad);&nbsp; &nbsp; }}🍍🥔🍵🍵🏺🎧🎚🎙⚔⌨🎳⛳🏓🌏🏝🏝🕘🕒🕢🕠🎵🔇🎸🗓🔏⛏🔒->🍍?🥔?🍵?🍵?🏺?🎧?🎚?🎙?⚔⌨🎳?⛳🏓?🌏?🏝?现在找到一个替代的 HTML 实体解码器......

喵喔喔

Is there a proper way to convert these characters into UTF8&nbsp;可能,如果您只是发送字符串,它将被转换为 UTF-8。这就是 Java 编码器的工作方式。如果没有并且您正在发送二进制文件,则可以直接转换:private&nbsp;static&nbsp;byte[]&nbsp;removeSurrogates(String&nbsp;query)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;query.getBytes(&nbsp;"UTF-8"&nbsp;); &nbsp;&nbsp;&nbsp;&nbsp;}

RISEBY

让我暂时离开 Java 来说明 BigQuery 可以处理表情符号:CREATE TABLE `public_dump.emoji_test`ASSELECT "🍍🥔🍵🍵🏺🎧🎚🎙⚔⌨🎳⛳🏓🌏🏝🏝🕘🕒🕢🕠🎵🔇🎸🗓🔏⛏🔒" emojis然后测试是否存在:SELECT COUNT(*)FROM `fh-bigquery.public_dump.emoji_test`WHERE emojis LIKE '%🎳%'1用 Python 做这件事很简单:插入新数据也不是问题:很抱歉,我不知道如何使用 Java 来解决这个问题,但我希望看到 BigQuery 的 API 能够优雅地处理表情符号的证明会有所帮助。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java