将 Locales 与 Java 的 toLowerCase() 和 toUpperCase() 一起使用

2022-08-31 11:05:23

我希望代码在Java中将字符串中的所有字符转换为大写或小写。

我发现了一个类似这样的方法:

public static String changelowertoupper()
{
         String str = "CyBeRdRaGoN";
         str=str.toLowerCase(Locale.ENGLISH);
         return str;
}

现在我已经读到,使用某些s,如土耳其语,“返回i(不带点)而不是i(带点)”。Locale

使用像英国,美国,英语等这样的s是否安全?当应用于字符串时,它们之间有什么大的区别吗?Locale

哪个是 s 最优选的?LocaleString


答案 1

我认为你应该使用区域设置,

例如,土耳其语区域设置中的“TITLE”.toLowerCase() 返回“tıtle”,其中“ı”是拉丁小写字母 DOTLESS I 字符。要获取对区域设置不敏感的字符串的正确结果,请使用 toLowerCase(Locale.ENGLISH)。

我将这些链接称为您的问题的解决方案,并且有必要记住您的情况“土耳其语”

**FROM THE LINKS**

toLowerCase() 尊重国际化 (i18n)。它执行相对于您的区域设置的大小写转换。当你调用LowerCase()时,内部对LowerCase(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”。

您是否注意到了该问题?这种不对称的转换会导致编程中的严重问题。我们主要在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”,其中“ı”是拉丁小写字母 DOTLESS I 字符。要获取对区域设置不敏感的字符串的正确结果,请使用 toLowerCase(Locale.ENGLISH)。


答案 2

您可以为您的语言创建适当的区域设置。String

例如:

toUpperCase(new Locale("tr","TR"));

将为土耳其人做把戏。