问题 具有不对称大写/小写的Unicode字符。为什么?


为什么以下三个字符不对称 toLowertoUpper 结果

/**
  * 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"

1823
2017-09-20 20:57


起源

也许是因为Unicode含糊不清?某些字形在Unicode中有多种表示形式 toLower 后 toUpper 反之亦然,规范化为“最低”代码点。
杰夫莫泽的优秀 土耳其测试站 特别是土耳其语问题。 - MPG


答案:


对于第一个,有 这个解释

在德语中,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(LATIN CAPITAL LETTER K)。这个似乎对我有意义。

对于第三种情况,U + 0130(拉丁语大写字母I上面有点)是土耳其语/阿塞拜疆语字符,小写字母为U + 0069(LATIN SMALL LETTER I)。我想如果你不知何故在土耳其/阿塞拜疆的地方,你会得到U + 0069的正确大写版本,但这可能不一定是普遍的。

字符不一定具有对称的大写和小写变换。

编辑: 为了回应下面的PhiLho评论, Unicode 6.0规范 关于U + 212A(KELVIN SIGN)有这个说法:

三个字母符号被赋予规范字母的规范等价:U + 2126   OHM SIGN, U + 212A KELVIN SIGN,和U + 212B ANGSTROM SIGN。在所有三个实例中,应使用常规字母。如果根据Unicode标准附件#15“Unicode规范化表单”对文本进行规范化,则这三个字符将被其常规等价物替换。

换句话说,你不应该真正使用U + 212A,你应该使用U + 004B(LATIN CAPITAL LETTER K),如果你规范化你的Unicode文本,U + 212A应该用U + 004B代替。


11
2017-09-20 21:07



我发现错误的是给出小写等效的开尔文符号,单位符号的情况永远不应该改变。 IE浏览器。即使在所有大写冠军中,人们都应该写道:“4小时内他们42公里”...... - PhiLho
人们总是对Unicode案件感到困惑,因为他们认为一切都像26个ASCII字母一样工作,但事实并非如此。例如,想想三个希腊sigma的情况。此外,还有一些小写代码点,在映射时不会改变大小写等。实际上有四种Unicode情况,在某种意义上,“折叠大小写”是第四种。要比较两个不区分大小写的字符串,必须将每个字符串映射到它们的大小写折叠并比较该映射的结果。 - tchrist
实际上,它不是关于Unicode,而是关于文化习俗。德国人将大写字母称为SS,Unicode只是为了纪念这种做法。 - Mihai Nita
@tchrist:映射到“折叠案例”,你会怎么做?将 uc(lc(c)) 做? - maaartinus
@maaartinus没有数量 uc 要么 lc 组合将可靠地使您进入Unicode提供的折叠大小写映射。这就是Perl提供的原因 fc 功能。如果您遇到Java,可能会查看ICU库,这可能有些东西。 - tchrist


我可以参考另一篇关于Unicode和大小写的帖子。 认为语言符号是一个常见的错误 不得不 有大小写可供选择!

Java中的Unicode纠正标题案例


3
2017-09-20 21:19



特别适用于表意文字...... :-) - PhiLho
你实际上不能在Java中使用Unicode正确的标题。只有一个 Character 方法,而不是 String 方法是大写和小写的方式。这是一个真正的问题。 - tchrist