如何识别字符串是否包含无法使用utf8-mb4字符集存储的特殊字符

时间:2012-01-09 06:27:48

标签: java encoding utf-8 character-encoding

请参阅此tweet以及以下thread我们正在尝试将类似的推文存储到数据库中。我无法在MySQL中存储此推文,我想知道如何识别,如果字符串包含一个无法由utf8-mb4字符集处理的字符,那么我可以避免存储它。

3 个答案:

答案 0 :(得分:4)

给您带来问题的字符是U+1F603 SMILING FACE WITH OPEN MOUTH,其值不能以16位表示。当转换为UTF-8时,字节值为f0 9f 98 83,这应该在utf8mb4字符集MySQL列中没有问题,所以我同意其他评论者认为它不是一个MySQL问题。如果您可以尝试重新插入此推文,请记录MySQL收到的所有SQL语句,以确定字符在发送到MySQL之前或之后是否已损坏。

答案 1 :(得分:1)

您可以做一件事,而不是找到字符串的特殊字符 您可以将字符串转换为十六进制格式然后返回,您可以将其转换为以前的字符串

public static synchronized String toHex(byte [] buf){
    StringBuffer strbuf = new StringBuffer(buf.length * 2);
    int i;
    for (i = 0; i < buf.length; i++) {
        if (((int) buf[i] & 0xff) < 0x10){
            strbuf.append("0");
        }
        strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
    }
    return strbuf.toString();
}

通过使用以下功能,您可以转换回原始字符串

public synchronized static byte[] hexToBytes(String hexString) {
    HexBinaryAdapter adapter = new HexBinaryAdapter();
    byte[] bytes = adapter.unmarshal(hexString);
    return bytes;
}

答案 2 :(得分:0)

如果你想避免存储麻烦的字符(基本多语言平面之外的罕见花哨字符,这会给你带来麻烦),你可以解析String个字符并丢弃String如果它包含Character.charCount返回2Character.isSupplementaryCodePoint返回true的代码点。

这样,就像你问的那样,你可以避免存储那些(出于某种原因)你的DBMS遇到问题的字符串。

来源:见

的javadoc
  • Character.charCount
  • Character.isSupplementaryCodePoint

并且,当你在它时

  • String.codePointAt
  • String.codePointCount