关于字符串:Java中的Unicode正确标题大小写

Unicode-correct title case in Java

我一直在浏览所有关于在Java中用大写字母的问题中的所有StAcExcel,它们似乎都不关心国际化问题,事实上,在国际环境中似乎没有一个是可行的。所以这是我的问题。

我在Java中有一个字符串,它代表一个单词-所有ISLITE()字符,没有空白。我想将第一个字符设为大写,其余的设为小写。我确实有我的词在手边的地方。

对于字符串的最后一部分,调用.substring(1).tolowercase(locale)已经很容易了。不过,我不知道如何得到正确的第一个字符。

我遇到的第一个问题是荷兰语,"ij"作为有向图应该一起大写。我可以用手特别说明这一点,因为我知道这一点;现在可能有其他语言有这种我不知道的东西,我相信Unicode会告诉我,如果我问得好的话。但我不知道该怎么问。

即使上面的问题解决了,我仍然没有合适的方法来处理英语、土耳其语和希腊语,因为字符支持titlecase,但不支持locale,字符串支持locales,但不支持titlecase。

如果我将代码点传递给character.toitlecase(),这将失败,因为无法将区域设置传递给此方法。因此,如果系统区域设置是英语,但单词是土耳其语,并且单词的第一个字符是"i",我将得到"i"而不是"?这是错误的。现在,如果我取一个子字符串并使用.touppercase(locale),这将失败,因为它是大写的,而不是标题。所以如果这个词是希腊语的话,我还是会搞错的。

如果有人有有用的指点,我会很高兴听到的。


像你一样,我在核心Java API中找不到合适的方法。

但是,在ICU库中似乎确实存在一个区分区域设置的字符串标题大小写方法(UCharacter#toTitleCase)。

从相关ICU方法(UCharacter#toTitleCaseUCaseProps#toUpperOrTitle的来源来看,似乎没有太多针对特定地区的标题大小写的特殊案例,因此您可以避开以下几点:

  • 在字符串中查找第一个大小写字符。
  • 如果它有一个不同于大写形式的标题大小写形式,请使用它。
  • 否则,对第一个字符及其组合字符执行区分区域设置的大写。
  • 对字符串的其余部分执行区分区域设置的小写。
  • 如果区域设置为荷兰语,并且第一个带大小写的字符是"i",后跟"j",则大写为"j"。

  • 只有两个字符的有向图,其中两个字符同时大写,您可能会在现实生活中遇到的程序是荷兰ij。如果地点是荷兰语,就处理它。在最不可能发生的情况下,会有1-2个案例需要稍后添加,这并不是说您每天都会遇到新的大写有向图,因此不值得在这里集中讨论泛化。

    注意,一般来说,不可能使用字符到字符的转换来获取任意语言的标题或大写。某些小写字符转换为多个大写字符。所以在一般情况下必须使用字符串。

    但是标题框区域设置没有任何问题。对于toitleCase()方法的工作方式,可能存在一个小的误解。它将转换为标题大小写任何字符,包括已经在大写的字符。

    例如,考虑?性格。它的大写形式是?标题形式是?:

    1
    2
    System.out.println(Character.toUpperCase('\u01C4'));
    ?

    1
    2
    System.out.println(Character.toTitleCase('\u01C4'));
    ?

    但是,以下也将给出标题案例

    1
    2
    System.out.println(Character.toTitleCase(Character.toUpperCase('\u01C4')));
    ?

    因此,如果在标题大小写之前将locale转换为大写,则会得到正确的代码点,并且在结果上使用标题大小写没有问题,包括土耳其语等:

    1
    2
    3
    4
    System.out.println(Character.toTitleCase("?".toUpperCase().charAt(0)));
    System.out.println(Character.toTitleCase("i".toUpperCase(Locale.forLanguageTag("tr")).charAt(0)));
    ?
    ?

    注意,在一般情况下,仅使用单个字符的标题大小写(如果其大小写不同)是不正确的。

    总结:

    • 处理荷兰语有向图(或者其他有向图,如果您遇到它们,我强烈怀疑,最坏情况下,它将是1-2个程序生命周期的情况)。
    • 使用locale和touppercase()将所需字符转换为字符串
    • 使用字符toitlecase转换touppercase结果的所有字符。

    注意,仍然有一些大写的情况是上下文感知的,例如爱尔兰前缀、英文FF名称等,这些情况不仅需要字符/字符串处理,但我怀疑您是否需要在程序中处理它们来生成标题。


    问题是,区分大小写字母是非常具体的语言。那么多,也许大多数语言,没有这样的语言。

    总之,有一个Unicode常见问题解答:http://www.unicode.org/faq/casemap_charprop.html

    …我想在某处有一个特定于Unicode的映射表(类似于ftp://ftp.unicode.org/public/unidata/unicodedata.txt)。所以最好使用自己的转换方法。