如何在没有未配对代理字符的情况下将表情符号等字符编码为 UTF8?
How can I encode characters like emojis as UTF8 without unpaired surrogate characters?
我有包含各种字符的字符串需要写入 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,并且不使用不成对的代理?
(抱歉,我对字符集的理解一般不是很好)
Is there a proper way to convert these characters into UTF8
如果您只是发送字符串,它可能会被转换为 UTF-8。 Java 的编码器就是这样工作的。
如果没有,而您发送的是二进制文件,您可以直接转换:
private static byte[] removeSurrogates(String query) {
return query.getBytes( "UTF-8" );
}
让我暂时离开 Java 以证明 BigQuery 可以处理表情符号:
CREATE TABLE `public_dump.emoji_test`
AS
SELECT "⚔⌨⛳⛏" emojis
然后测试是否存在:
SELECT COUNT(*)
FROM `fh-bigquery.public_dump.emoji_test`
WHERE emojis LIKE '%%'
1
用 Python 做这个很简单:
插入新数据也不是问题:
很抱歉,我不知道如何使用 Java 解决此问题,但我希望看到这个证明 BigQuery API 优雅处理表情符号的能力的证明会有所帮助。
我发现了问题。我们正在使用 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 实体解码器...
我有包含各种字符的字符串需要写入 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,并且不使用不成对的代理?
(抱歉,我对字符集的理解一般不是很好)
Is there a proper way to convert these characters into UTF8
如果您只是发送字符串,它可能会被转换为 UTF-8。 Java 的编码器就是这样工作的。
如果没有,而您发送的是二进制文件,您可以直接转换:
private static byte[] removeSurrogates(String query) {
return query.getBytes( "UTF-8" );
}
让我暂时离开 Java 以证明 BigQuery 可以处理表情符号:
CREATE TABLE `public_dump.emoji_test`
AS
SELECT "⚔⌨⛳⛏" emojis
然后测试是否存在:
SELECT COUNT(*)
FROM `fh-bigquery.public_dump.emoji_test`
WHERE emojis LIKE '%%'
1
用 Python 做这个很简单:
插入新数据也不是问题:
很抱歉,我不知道如何使用 Java 解决此问题,但我希望看到这个证明 BigQuery API 优雅处理表情符号的能力的证明会有所帮助。
我发现了问题。我们正在使用 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 实体解码器...