【问题标题】:Split UTF-16 String into single chars/strings将 UTF-16 字符串拆分为单个字符/字符串
【发布时间】:2018-07-05 08:46:29
【问题描述】:

我有一个类似于 a????b????c 的字符串,我想将其拆分为单个字符/字符串。

static List<String> split(String text ) {
    List<String> list = new ArrayList<>(text.length());
    for(int i = 0; i < text.length() ; i++) {
        list.add(text.substring(i, i + 1));
    }
    return list;
}

public static void main(String... args) {
    split("a\uD83D\uDC4Fb\uD83D\uDE42c")
            .forEach(System.out::println);
}

您可能已经注意到,而不是 ????和 ????我得到了两个奇怪的字符:

a
?
?
b
?
?
c

【问题讨论】:

  • 那些不是 UTF-16 字符,这就是问题所在。这些是 UTF-32 代码点。
  • 如答案所示,这可以相当容易地完成。但是,一旦您尝试尝试将呈现为单个字形的字符组合起来,它就会变成另一种地狱。

标签: java utf-16


【解决方案1】:

以下将完成这项工作:

List<String> split(String text) {
    return text.codePoints()
            .mapToObj(Character::toChars)
            .map(String::valueOf)
            .collect(Collectors.toList());
}

【讨论】:

    【解决方案2】:

    根据Character and String APIs docs,您需要使用代码点来正确处理 UTF 多字节序列。

    "a?b?c".codePoints().mapToObj(Character::toChars).forEach(System.out::println);
    

    会输出

    a
    ?
    b
    ?
    c
    

    【讨论】:

    • 我怎样才能把那些codePoints 改成字符串呢?
    【解决方案3】:

    有一个开源 MgntUtils 库(由我编写),它具有将任何字符串转换为 unicode 和反之亦然(正确处理代码点)的实用程序,这可以帮助您处理问题并了解内部工作在科学背后进行。这是一个例子:

    下面的代码

    String result = "a?b?c";
    result = StringUnicodeEncoderDecoder.encodeStringToUnicodeSequence(result);
    System.out.println(result);
    result = StringUnicodeEncoderDecoder.decodeUnicodeSequenceToString(result);
    System.out.println(result);
    

    会产生以下结果:

    \u0061\u1f44f\u0062\u1f642\u0063
    a?b?c
    

    这里是文章的链接,该文章解释了 MgntUtils 库以及从何处获取它(包括 javadoc 和源代码):Open Source Java library with stack trace filtering, Silent String parsing Unicode converter and Version comparison。查找段落“字符串 Unicode 转换器

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-08
      • 1970-01-01
      • 2022-09-27
      • 2010-09-21
      • 2014-02-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多