【问题标题】:Unicode characters having asymmetric upper/lower case. Why?大小写不对称的 Unicode 字符。为什么?
【发布时间】:2011-11-21 10:39:36
【问题描述】:

为什么下面三个字符没有对称toLower,toUpper结果

/**
  * Written in the Scala programming language, typed into the Scala REPL.
  * Results commented accordingly.
  */
/* Unicode Character 'LATIN CAPITAL LETTER SHARP S' (U+1E9E) */
'\u1e9e'.toHexString == "1e9e" // true
'\u1e9e'.toLower.toHexString == "df" // "df" == "df"
'\u1e9e'.toHexString == '\u1e9e'.toLower.toUpper.toHexString // "1e9e" != "df"
/* Unicode Character 'KELVIN SIGN' (U+212A) */
'\u212a'.toHexString == "212a" // "212a" == "212a"
'\u212a'.toLower.toHexString == "6b" // "6b" == "6b"
'\u212a'.toHexString == '\u212a'.toLower.toUpper.toHexString // "212a" != "4b"
/* Unicode Character 'LATIN CAPITAL LETTER I WITH DOT ABOVE' (U+0130) */
'\u0130'.toHexString == "130" // "130" == "130"
'\u0130'.toLower.toHexString == "69" // "69" == "69"
'\u0130'.toHexString == '\u0130'.toLower.toUpper.toHexString // "130" != "49"

【问题讨论】:

  • 也许是因为 Unicode 不明确?一些字形在 Unicode 中有多种表示形式,toLowertoUpper 之后,反之亦然,标准化为“最低”代码点。
  • Jeff Moser 的出色 Turkey Test post 尤其涵盖了土耳其语 I 问题。

标签: unicode uppercase lowercase symmetry case-conversion


【解决方案1】:

对于第一个,有this explanation

在德语中,Sharp S(“ß”或 U+00df)是小写字母,大写字母“SS”。

也就是说,U+1E9E小写为U+00DF,但U+00DF的大写不是U+1E9E。

对于第二个,U+212A (KELVIN SIGN) 小写为 U+0068 (LATIN SMALL LETTER K)。 U+0068 的大写字母是 U+004B(拉丁文大写字母 K)。这对我来说似乎很有意义。

对于第三种情况,U+0130(上方带点的拉丁文大写字母 I)是土耳其语/阿塞拜疆语字符,小写为 U+0069(拉丁文小写字母 I)。我想如果你在土耳其/阿塞拜疆语言环境中,你会得到 U+0069 的正确大写版本,但这可能不一定是通用的。

字符不一定要有对称的大小写转换。

编辑:为了回应 PhiLho 在下面的评论,Unicode 6.0 spec 对 U+212A(KELVIN SIGN)有这样的看法:

三个类似字母的符号已被赋予与常规字母等价的规范:U+2126 OHM 标志、U+212A KELVIN 标志和 U+212B ANGSTROM 标志。在所有三种情况下,都应使用常规字母。如果根据 Unicode 标准附件 #15“Unicode 规范化形式”对文本进行规范化,这三个字符将被它们的常规等效字符替换。

换句话说,你不应该真的使用 U+212A,你应该使用 U+004B(拉丁大写字母 K),如果你规范化你的 Unicode 文本,U+212A 应该替换为 U+ 004B.

【讨论】:

  • 我发现给出开尔文符号的小写等效项是错误的,单位符号的大小写永远不应更改。 IE。即使是全部大写的标题,也应该真正写:“HE RAN 42 km IN 4 h”...
  • 人们总是对 Unicode 大小写感到困惑,因为他们认为一切都像 26 个 ASCII 字母一样工作,但事实并非如此。例如,想想三个希腊 sigma 的情况。此外,还有一些小写代码点在映射时不会改变大小写等。实际上有四种 Unicode 大小写,从某种意义上说,“折叠大小写”是第四种。要不区分大小写地比较两个字符串,您必须将每个字符串映射到它们的大小写折叠并比较该映射的结果。
  • 实际上,与其说是 Unicode,不如说是文化惯例。德国人将 s 大写为 SS,Unicode 只尊重这种做法。
  • @tchrist:映射到“折叠案例”,你会怎么做? uc(lc(c)) 会吗?
  • @maaartinus 没有多少uclc 组合可以可靠地让您获得Unicode 提供的折叠大小写映射。这就是 Perl 提供fc 函数的原因。如果您被 Java 困住,您可能会查看 ICU 库,其中可能有一些东西。
【解决方案2】:

我可以参考另一篇关于 Unicode 和大小写的帖子。 认为一种语言的符号必须以大写和小写形式出现是一个常见的错误!

Unicode-correct title case in Java

【讨论】:

  • 对表意文字尤其如此... :-)
  • 您实际上无法在 Java 中进行 Unicode 正确的标题大小写。只有Character 方法,而不是String 方法,用于大写和小写。这是一个真正的问题。
猜你喜欢
  • 1970-01-01
  • 2010-10-30
  • 2016-03-29
  • 1970-01-01
  • 1970-01-01
  • 2011-04-01
  • 1970-01-01
  • 2010-09-22
  • 1970-01-01
相关资源
最近更新 更多