我如何在Java中替换不可打印的Unicode字符?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (46)

以下内容将取代ASCII控制字符(简写为[\x00-\x1F\x7F]):

my_string.replaceAll("\\p{Cntrl}", "?");

以下内容将替换所有ASCII非打印字符(简写为[\p{Graph}\x20]),包括重音字符:

my_string.replaceAll("[^\\p{Print}]", "?");

但是,它们都不适用于Unicode字符串。有没有人有一个很好的方法来从unicode字符串中删除不可打印的字符?

提问于
用户回答回答于
用户回答回答于

Op De Cirkel大部分都是正确的。他的建议在大多数情况下都适用:

myString.replaceAll("\\p{C}", "?");

但是如果myString可能包含非BMP代码点,那么它更复杂。 \p{C}包含的替代码点\p{Cs}。上述替换方法有时会替换只有一半的代理对,从而破坏非BMP代码点。这可能是Java错误而不是预期的行为。

使用其他组成部分是一种选择:

myString.replaceAll("[\\p{Cc}\\p{Cf}\\p{Co}\\p{Cn}]", "?");

然而,单个替代字符不是一对(每个替代字符都有一个分配的码点)的一部分不会被删除。非正则表达式方法是我知道要正确处理的唯一方法\p{C}

StringBuilder newString = new StringBuilder(myString.length());
for (int offset = 0; offset < myString.length();)
{
    int codePoint = myString.codePointAt(offset);
    offset += Character.charCount(codePoint);

    // Replace invisible control characters and unused code points
    switch (Character.getType(codePoint))
    {
        case Character.CONTROL:     // \p{Cc}
        case Character.FORMAT:      // \p{Cf}
        case Character.PRIVATE_USE: // \p{Co}
        case Character.SURROGATE:   // \p{Cs}
        case Character.UNASSIGNED:  // \p{Cn}
            newString.append('?');
            break;
        default:
            newString.append(Character.toChars(codePoint));
            break;
    }
}

扫码关注云+社区