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

时间:2015-10-06 09:10:07

标签: 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();

我们可以turkish example: 当它移动到大写时,小写“i”变为“İ”(U + 0130“拉丁大写字母I,上面有点”)。同样,当它移动到小写时,我们的大写“I”变成“ı”(U + 0131“Latin Small Letter Dotless I”)。

to upper

to lower

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

4 个答案:

答案 0 :(得分:2)

不变文化是一种基于英语的假文化,因此所有“不变”转换都将基于英语转换。

  

对于每个小写字符,世界上所有语言都是大写的吗?

不,他们没有。例如,中文没有大写和小写的概念。

德语有字母ß,没有大写版本。

考虑:

var germanCulture = new CultureInfo("de-DE");

System.Threading.Thread.CurrentThread.CurrentCulture   = germanCulture;
System.Threading.Thread.CurrentThread.CurrentUICulture = germanCulture;

string s = "ß";

Console.WriteLine(s.ToUpper()); // Prints ß
Console.WriteLine(s.ToLower()); // Prints ß

// Aside: There's a special "uppercase" ß, but this isn't
// returned from "ß".ToUpper();

string t = "ẞ"; // Special "uppercase" ß.

Console.WriteLine(t == s); // Prints false.

Console.WriteLine(s.ToUpper() == t); // Prints false.

(有关未从ß返回的奇怪大写"ß".ToUpper())的详细信息,请参阅here。)

答案 1 :(得分:1)

请参阅MSDN备注:

  

不变文化代表着一种文化   文化不敏感。 它与英语相关但是   与特定国家或地区无关。

并非所有语言都有大写和小写字符,如中文,日文,印地文,马拉地语等

另外this

  

ToLower在大多数地方与ToLowerInvariant非常相似。该   文件表明这些方法只会改变行为   土耳其文化。此外,在Windows系统上,文件系统是   不区分大小写,这进一步限制了它的使用

答案 2 :(得分:1)

根据Unicode standard,案例映射信息的来源是

  

UnicodeData.txt:包含映射到单个字符的大小写映射。这些不会增加字符串的长度,也不会包含依赖于上下文的映射。

     

SpecialCasing.txt:包含映射到多个字符的其他大小写映射,例如“ß”到“SS”。还包含依赖于上下文的映射,带有标志以区别于正常映射,以及一些与语言环境相关的映射。

UnicodeData.txt中,您会找到:

0069;LATIN SMALL LETTER I;Ll;0;L;;;;;N;;;0049;;0049
010C;LATIN CAPITAL LETTER C WITH CARON;Lu;0;L;0043 030C;;;;N;LATIN CAPITAL LETTER C HACEK;;;010D;
010D;LATIN SMALL LETTER C WITH CARON;Ll;0;L;0063 030C;;;;N;LATIN SMALL LETTER C HACEK;;010C;;010C

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

因此,除非存在依赖于语言环境的异常,否则每个 Unicode实现都将使用这些映射,从而导致:

uppercase(i) = I
uppercase(č) = Č
lowercase(Č) = č

文件SpecialCasing.txt说:

  

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

     

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

  

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

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

# When uppercasing, i turns into a dotted capital I

0069; 0069; 0130; 0130; tr; # LATIN SMALL LETTER I

所以,对于土耳其语(和阿塞拜疆语):

uppercase(i) = İ

立陶宛语也有一些例外。除了这些少数例外,无论.NET“文化”如何,案例映射都应该始终相同。

答案 3 :(得分:0)

我正在补充一些重点: -

  1. 不变文化对文化不敏感;它与英语有关,但与任何国家/地区无关。

  2. 通过使用不变文化,可以解决字符串表示问题,并且由于国家或地区的变化,它不会发生变化。

  3.   

    示例:我们在IST中显示一些日期 dd / MM / YYYY ,但在EST中它可能会通过一些异常或获得不同的含义,所以从类似的问题出来,我们可以使用不变量概念