String.ToLowerInvariant() 如何确定它必须转换为哪个字符串/字符?

bro*_*and 5 c# unicode

正如我们所知,Unicode 的发明是为了解决代码页问题并表示世界上所有(不是所有但大多数)语言的所有字符。接下来我们有 unicode 转换格式 - 如何以计算机字节表示 unicode 字符:

  • utf-8 一个字符可以占用 1 到 4 个字节
  • utf-16 一个字符需要 2 个字节,或者 2*2bytes = 4bytes(.NET 使用这个)
  • utf-32 一个字符总是需要 4 个字节(我听说 Python 使用这个)

到目前为止,还好。接下来我们以两种语言为例:

英国的英语 (en-GB) 和斯洛文尼亚的斯洛文尼亚语 (sl-SI)。英语有下一个字符:a, b, c, d, e, ... x, y, z。除了 x,y 之外,斯洛文尼亚语具有相同的字符,并且还有其他字符:?、š、ž。如果我运行以下代码:

Thread.CurrentThread.CurrentCulture = new CultureInfo("sl-SI");
string upperCase = "?".ToUpper(); // returns ?, which is correct based on sl-SI culture

// returns ?, how does it know that it must convert ? to ?. 
// What if some other language has character ?, and ? in that language converts to X.
// How does it determine to what character it must convert?
Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR");
string upperCase1 = "?".ToUpperInvariant();
Run Code Online (Sandbox Code Playgroud)

我们可以以土耳其语为例:小写的“i”变成“?” (U+0130 “拉丁大写字母 I,上面有点”)当它移动到大写时。同样,我们的大写“I”变成了“?” (U+0131 “拉丁小写字母无点 I”) 当它移动到小写时。

到上

降低

如果 ToUpperInvariant() 决定将“i”转换为土耳其语“”怎么办?而不是“我”。然后是不变文化英语。超出了这个问题的范围,但是,世界上所有语言的每个小写字符都有大写吗?我假设是的,但如果他们不这样做,是否有一种语言只有大写字符。是的,我知道我应该从 \u+0000 到 \u+FFFF 来测试这个。

nwe*_*hof 1

根据Unicode标准,大小写映射信息的来源是

\n
\n

UnicodeData.txt:包含映射到单个字符的大小写映射。它们不会增加字符串的长度,也不包含上下文相关的映射。

\n

SpecialCasing.txt:包含映射到多个字符的其他大小写映射,例如 \xe2\x80\x9c\xc3\x9f\xe2\x80\x9d 到 \xe2\x80\x9cSS\xe2\x80\x9d。还包含上下文相关的映射(带有用于将它们与普通映射区分开的标志)以及一些与语言环境相关的映射。

\n
\n

UnicodeData.txt中,您会发现:

\n
0069;LATIN SMALL LETTER I;Ll;0;L;;;;;N;;;0049;;0049\n010C;LATIN CAPITAL LETTER C WITH CARON;Lu;0;L;0043 030C;;;;N;LATIN CAPITAL LETTER C HACEK;;;010D;\n010D;LATIN SMALL LETTER C WITH CARON;Ll;0;L;0063 030C;;;;N;LATIN SMALL LETTER C HACEK;;010C;;010C\n
Run Code Online (Sandbox Code Playgroud)\n

(最后三列包含简单的大写、小写和标题大写映射。)

\n

因此,除非存在与区域设置相关的异常,否则每个Unicode 实现都将使用这些映射,从而导致:

\n
uppercase(i) = I\nuppercase(\xc4\x8d) = \xc4\x8c\nlowercase(\xc4\x8c) = \xc4\x8d\n
Run Code Online (Sandbox Code Playgroud)\n

文件SpecialCasing.txt说:

\n
\n

该文件中的条目采用以下机器可读格式:

\n

<code>; <lower>; <title>; <upper>; (<condition_list>;)? # <comment>

\n
\n

\n
\n

如果所有列出的条件都为真,则条件列表将覆盖正常行为。

\n
\n

对于土耳其语,它包含以下例外:

\n
# When uppercasing, i turns into a dotted capital I\n\n0069; 0069; 0130; 0130; tr; # LATIN SMALL LETTER I\n
Run Code Online (Sandbox Code Playgroud)\n

因此,对于土耳其语(和阿塞拜疆语):

\n
uppercase(i) = \xc4\xb0\n
Run Code Online (Sandbox Code Playgroud)\n

立陶宛语也有一些例外。除了这几个例外之外,无论 .NET“文化”如何,大小写映射都应始终相同。

\n