【问题标题】:Why java String treat some UTF-8 symbols as several characters为什么 java String 将某些 UTF-8 符号视为多个字符
【发布时间】:2018-01-24 12:54:03
【问题描述】:

我试图涵盖 utf-8 符号,但 java String 有时会将 1 个符号转换为多个符号。将其写入文件并在编辑器中显示效果很好,但我需要检查有效的 java 标识符,这些标识符甚至可以写成 4 个字节,例如下一个音调的“f0 93 81 98”:

U+0080-U+07FF (110xxxxx 10xxxxxx)

字符串将其拆分为 2 个符号。 所以问题是如何从 utf-8 字节数组中获取正确的字符串。这是我的代码示例:

    byte[] test = {0, 0};
    int tmp;//use tmp int to avoid negative pointer bit mess
    for (int a = 12; a < 14; a++) {//110x mask
        for (int b = 0; b < 16; b++) {
            tmp = a << 4;
            tmp |= b;
            test[0] = (byte) tmp;
            for (int c = 8; c < 14; c++) {//10xx mask
                for (int d = 0; d < 16; d++) {
                    tmp = c << 4;
                    tmp |=d;
                    test[1] = (byte) tmp;

                    String symbol = new String(test, "UTF-8");
                    System.out.println(symbol.codePoints().count());//as Josh Lee commented
                }
            }
        }
    }

【问题讨论】:

标签: java string utf-8


【解决方案1】:

Java String 对象是char 的序列,它们是UTF-16 值。要处理所有 Unicode,您需要查找 codePoint 构造函数和方法(使用 int 作为代码点的表示)。

byte[] b = new byte[]{
    (byte)0xf0, (byte)0x93, (byte)0x81, (byte)0x98};
String s = new String(b, "UTF-8");
System.out.println(s.length());  // 2
System.out.println(s.codePoints().count());  // 1

您的特定字符 U+13058 具有 0xD80C 0xDC58 的 UTF-16 表示。

至于如何将UTF-8字节转为String的问题,Java标准库可以帮你解决,无论是直接调用String构造函数还是构造InputStreamReader的时候。

【讨论】:

  • 谢谢。这带来了一些亮点,但对于我的代码,对于某些值,我仍然有 2 个代码点。
猜你喜欢
  • 2015-06-05
  • 2016-10-14
  • 1970-01-01
  • 2015-12-05
  • 1970-01-01
  • 2016-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多