如何获取反向字符串(unicode安全)
让我们假设我们要还原以下字符串“áe”。
该代码为“ \ u0061 \ u0301 \ u0065”。
恢复它的幼稚方法是逐个字符
private static String reverseStringNaive(String s) { char[] characters = new char[s.length()];
for (int i = s.length() - 1; i >= 0; i--) {
int j = s.length() - i - 1;
characters[j] = s.charAt(i);
}
return new String(characters);
}
当我们希望获得“eá”(\ u0065 \ u0061 \ u0301)时,它会给我们“éa”(\ u0065 \ u0301 \
u0061)。重音“´”应与“ a”粘贴在一起,而不要更改为“ e”。
以下代码为我提供了该字符串的预期结果:
private static String reverseString(String s) { char[] characters = new char[s.length()];
for (int i = s.length() - 1; i >= 0; i--) {
int j = s.length() - i - 1;
if (Character.isLetterOrDigit(s.charAt(i)) || Character.isISOControl(s.charAt(i))) {
characters[j] = s.charAt(i);
} else {
characters[j] = s.charAt(i-1);
characters[j+1] = s.charAt(i);
i--;
}
}
return new String(characters);
}
我正在检查每个字符是否为字母,数字或ISO控件。如果不是,我假设它应该与前一个字符结合在一起。
问题是,还有其他我应该检查或担心的事情吗?我的方法还是很幼稚吗?
回答:
您也可以通过将字符串转换为NFC规范分解来解决您的问题。基本上,java.text.Normalizer类可用于组合重音符号和其他组合字符及其基本字符,因此您将能够正确地进行反转。
所有其他这些想法(String.reverse(),StringBuffer.reverse())将正确反转缓冲区中的字符,但是如果以分解的字符开头,则可能无法获得期望的结果:)。
在某些“分解形式”中,重音字符与其基本形式分开存储(作为单独的字符),但在“组合”形式中却不是。因此,“
ae”以一种形式存储为三个字符,而另一种以组合形式存储为两个字符。
但是,这样的规范化不足以处理其他类型的字符组合,也无法解决Unicode星体平面中的字符,这些字符在Java中存储为两个字符(或更多?)。
感谢tchrist指出了ICU对文本分割的支持,包括扩展的字素簇,例如下面的注释中所标识的(参见virama)。
此资源似乎是此类资料的权威信息来源。
以上是 如何获取反向字符串(unicode安全) 的全部内容, 来源链接: utcz.com/qa/415851.html