我认为你应该使用 locale ,
例如,土耳其语言环境中的 "TITLE".toLowerCase() 返回 "tıtle",其中 'ı' 是 LATIN SMALL LETTER DOTLESS I 字符。要获得不区分区域设置的字符串的正确结果,请使用 toLowerCase(Locale.ENGLISH)。
我将这些链接称为解决您的问题的方法,并且在您遇到“土耳其语”时要牢记这一点
**FROM THE LINKS**
toLowerCase() 尊重国际化 (i18n)。它针对您的区域设置执行大小写转换。当您调用 toLowerCase() 时,内部会调用 toLowerCase(Locale.getDefault())。它对语言环境敏感,您不应围绕它编写逻辑来独立解释语言环境。
import java.util.Locale;
public class ToLocaleTest {
public static void main(String[] args) throws Exception {
Locale.setDefault(new Locale("lt")); //setting Lithuanian as locale
String str = "\u00cc";
System.out.println("Before case conversion is "+str+
" and length is "+str.length());// Ì
String lowerCaseStr = str.toLowerCase();
System.out.println("Lower case is "+lowerCaseStr+
" and length is "+lowerCaseStr.length());// iı`
}
}
在上面的程序中,看一下转换前后的字符串长度。它将是 1 和 3。是的,大小写转换前后的字符串长度不同。当您在这种情况下依赖字符串长度时,您的逻辑将被折腾。当您的程序在不同的环境中执行时,它可能会失败。这将是代码审查中的一个很好的收获。
为了使其更安全,您可以使用另一种方法 toLowerCase(Locale.English) 并始终将语言环境覆盖为英语。但是你没有国际化。
所以关键是, toLowerCase() 是特定于语言环境的。
参考 1
参考 2
参考 3
Dotless-i,是没有点的小写“i”。这个字符的大写是通常的“I”。还有一个字符,“I with dot”。这个字符的小写字母是通常的小写字母“i”。
你注意到问题了吗?这种非对称转换会导致编程中的严重问题。我们主要在 Java 应用程序中遇到这个问题,因为(恕我直言)toLowerCase 和 toUpperCase 函数的实现很差。
在 Java 中,String.toLowerCase() 方法根据默认语言环境将字符转换为小写。如果您的应用程序在土耳其语言环境中工作,尤其是当您将此函数用于必须遵守特定字符集的文件名或 url 时,这会导致问题。
我之前在博客上写过两个严重的例子:名称中带有“i”的脚本库的编译错误以及如果 XPage 位于名称中带有“I”的数据库中,则 XSP 管理器的错误。
正如我所说,历史悠久。例如,在某些 R7 版本中,如果收件人的姓名以“I”开头,则路由器无法向收件人发送消息。直到 R8,消息报告代理才在土耳其语言环境中运行。任何使用土耳其语言环境的人都无法安装 Lotus Notes 8.5.1(这是真的!)。名单还在继续……
土耳其几乎没有 beta 测试人员,客户也不会为这些问题打开 PMR。所以这些问题并不是开发团队的首要任务。
甚至 Java 团队也在最新的文档中添加了特别警告:
此方法对语言环境敏感,如果用于旨在独立解释语言环境的字符串,可能会产生意外结果。示例是编程语言标识符、协议键和 HTML 标记。例如,土耳其语言环境中的 "TITLE".toLowerCase() 返回 "tıtle",其中 'ı' 是 LATIN SMALL LETTER DOTLESS I 字符。要获得不区分区域设置的字符串的正确结果,请使用 toLowerCase(Locale.ENGLISH)。