就在前几天,我遇到了一个奇怪的怪虫。我有一串我必须建立的角色。作为主机系统的分隔符,我正在使用char 254进行通信。无论如何,我构建了我的字符串并将其发送给主机。在主机上我收到了char 222作为分隔符!在抓了我的头,然后深入地看着它似乎很奇怪
hex:FE,二进制:11111110
正在变成
hex:DE,二进制:11011110
我尝试了Locale.getDefault()和Locale.ENGLISH无济于事。
String.toUpperCase的实现是否具有除特定硬编码之外的所有字符的掩码?
目前我正在使用以下方法解决问题:
public static String toUpperCase(String input) {
char[] chars = input.toCharArray();
for(int i = 0; i < chars.length; ++i ) {
if( chars[i] > 96 && chars[i] < 123 ) {
chars[i] &= 223;
}
}
return new String(chars);
}
我的问题是我错过了什么吗?有没有更好的方式我不知道?谢谢你!
答案 0 :(得分:7)
Unicode字符254是小写的刺,þ
,冰岛语中使用的一个大致代表“th”声音的字母。它的大写版本是字符222,大写刺Þ
。你期望会发生什么?
答案 1 :(得分:3)
Java一般使用UTF-16
。 Java中char
基元类型的前256个值与Latin-1字符集完全相同,后者给出here。在该图表上,您可以看到大写值254(低冰岛刺)将其转换为值222(冰岛上游刺)。
道德是:不要在字符串中使用具有大小写分隔符的值。
答案 2 :(得分:2)
根据http://www.unicode.org/faq/casemap_charprop.html:
Unicode标准定义了每个的默认案例映射 个性,每个角色都被孤立地考虑。 此映射不提供字符所在的上下文 出现,也不适用于必须应用的特定于语言的规则 使用自然语言文本。
所以看起来upper/lowerCase
方法的工作方式几乎相同,无论您使用的是哪种Locale。指定不同的区域设置可能会影响一些特定的字母(如土耳其语中的“i”),但它不会使upper/lowerCase
停止处理整组字母。因此,指定Locale.ENGLISH不会使upperCase
忽略冰岛字母 - 或俄语或希腊字母。
答案 3 :(得分:1)
String.toUpperCase()不能执行任何操作,只能在给定的char集中转换为大写。
您的问题似乎暗示您的系统与主机之间的链接是使用8位字符集(ASCII?)完成的。但是,Java在各种字符集(UTF-16,UTF-8等)中使用16位字符。因此,在解释字符集和转换为8位时,必须要进行转换。如果字符集是UTF-8,则前127个字符用ASCII映射1-1。但是,您关注的是该范围之外的字符,因此需要进行更复杂的转换。我猜这就是问题所在。
所以我认为你应该:
我猜这个奇怪的行为就在那里。
抱歉,我无法提供更多帮助。如果您向我提供有关通信链接和转换过程的更多详细信息,我可能会更清楚地了解正在发生的事情
答案 4 :(得分:1)
Locale trlocale= Locale.forLanguageTag("tr-TR");
Locale enLocale = Locale.forLanguageTag("en_US");
System.out.println("üğişçö".toUpperCase(new java.util.Locale("tr", "TR")));
System.out.println("üğişçö".toUpperCase(new java.util.Locale("en", "EN")));
value = new String(value.getBytes("UTF-8"), "UTF-8");