java - 一个 21 字节的 UTF-8 序列如何来自 5 个字符?

标签 java unicode encoding utf-8 string-length

在编写了一些基本代码来计算 String 中的字符数之后,我发现了一个示例,其中 UTF-8 编码输出从 5 个“字符” 中创建了 21 个字节字符串.

这是输出:

String ==¦ อภิชาติ ¦==
Code units 7
UTF8 Bytes 21
8859 Bytes 7
Characters 5

我了解 Java 对 char 的内部表示是 2 个字节,并且某些字符可能需要两个 Unicode 代码单元才能显示它们。

由于 UTF-8 每个字符不使用超过 4 个字节,对于 5 个字符的 Stringbyte[] 长度如何可能超过 20 ?

这是来源:

import java.io.UnsupportedEncodingException;

public class StringTest {

    public static void main(String[] args) {
        displayStringInfo("อภิชาติ");
    }

    public static void displayStringInfo(String s) {
        System.out.println("Code units " + s.length());     
        try {
            System.out.println("UTF8 Bytes " + s.getBytes("UTF-8").length);
        } catch (UnsupportedEncodingException e) { // not handled }
        System.out.println("Characters " + characterLength(s));
    }

    public static int characterLength(String s) {
        int count = 0;
        for(int i=0; i<s.length(); i++) {
            if(!isLeadingUnit(s.charAt(i)) && !isMark(s.charAt(i))) count++;
        }
        return count;
    }

    private static boolean isMark(char ch) {
        int type = Character.getType(ch);
        return (type == Character.NON_SPACING_MARK ||
               type == Character.ENCLOSING_MARK ||
               type == Character.COMBINING_SPACING_MARK);
    }

    private static boolean isLeadingUnit(char ch) {
        return Character.isHighSurrogate(ch);
    }
}

最佳答案

您的“5 个字符”字符串实际上由 7 个 Unicode 代码点组成:

  • U+0E2D 泰国字符 O ANG
  • U+0E20 泰国字符 PHO SAMPHAO
  • U+0E34 泰国字符 SARA I
  • U+0E0A 泰国字符 CHO CHANG
  • U+0E32 泰文字符 SARA AA
  • U+0E15 泰国字符 TO TAO
  • U+0E34 泰国字符 SARA I

它们都在 U+0800 到 U+FFFF 范围内,在 UTF-8 中每个字符需要 3 个字节,因此总长度为 7×3 = 21 个字节。

关于java - 一个 21 字节的 UTF-8 序列如何来自 5 个字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27707750/

相关文章:

assembly - 'escape opcode' 是什么意思?

java - 如何使用流在 java 中生成列表的映射 (Map<String, Map<Enum, List<String>>>)

java - 如何获取具有不同属性的XML标签的值?

java - 调用 OOM killer

python - 仅匹配 Python re 中的 unicode 字母

python - 这个字符 - ㎜ - 引发 UnicodeEncodeError

python - 如何在 Python 中获取 ASCII 西里尔字符代码?

encoding - 某些浏览器会对 cookie 进行编码吗?

java - 泛型方法继承

ios - UITextView 无法正确显示字母