Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# String.starts是否不使用亚洲语言?_C#_.net_String - Fatal编程技术网

C# String.starts是否不使用亚洲语言?

C# String.starts是否不使用亚洲语言?,c#,.net,string,C#,.net,String,我注意到了这个奇怪的问题。查看以下越南语(根据)字符串: 在我看来,这似乎是一个错误的结果。因此,我实现了我的自定义StartWith函数,它将字符串逐字符进行比较 这是怎么回事?!这是怎么可能的?StartsWith返回的结果是正确的。默认情况下,大多数字符串比较方法使用当前区域性而不是普通字节序列执行区域性敏感比较。尽管您的行以与sub相同的字节序列开头,但它所表示的子字符串在大多数(或所有)区域性下并不等效 如果确实需要将字符串视为普通字节序列的比较,请使用重载: line.StartsW

我注意到了这个奇怪的问题。查看以下越南语(根据)字符串:

在我看来,这似乎是一个错误的结果。因此,我实现了我的自定义
StartWith
函数,它将字符串逐字符进行比较


这是怎么回事?!这是怎么可能的?

StartsWith返回的结果是正确的。默认情况下,大多数字符串比较方法使用当前区域性而不是普通字节序列执行区域性敏感比较。尽管您的
以与
sub
相同的字节序列开头,但它所表示的子字符串在大多数(或所有)区域性下并不等效

如果确实需要将字符串视为普通字节序列的比较,请使用重载:

line.StartsWith(sub, StringComparison.Ordinal);                       // true
如果希望比较不区分大小写:

line.StartsWith(sub, StringComparison.OrdinalIgnoreCase);             // true
这里有一个更熟悉的例子:

var line1 = "café";   // 63 61 66 E9     – precomposed character 'é' (U+00E9)
var line2 = "café";   // 63 61 66 65 301 – base letter e (U+0065) and
                      //                   combining acute accent (U+0301)
var sub   = "cafe";   // 63 61 66 65 
Console.WriteLine(line1.StartsWith(sub));                             // false
Console.WriteLine(line2.StartsWith(sub));                             // false
Console.WriteLine(line1.StartsWith(sub, StringComparison.Ordinal));   // false
Console.WriteLine(line2.StartsWith(sub, StringComparison.Ordinal));   // true
string line = "Mìng-dĕ̤ng-ngṳ̄";   // 4D EC 6E 67 2D 64 115 324 6E 67 2D 6E 67 1E73 304
string sub  = "Mìng-dĕ̤ng-ngṳ";   // 4D EC 6E 67 2D 64 115 324 6E 67 2D 6E 67 1E73
在上述示例中,
line2
以与
sub
相同的字节序列开始,然后是一个组合的锐重音(U+0301),应用于最后的
e
<代码>第1行使用for
é
(U+00E9),因此其字节序列与
的字节序列不匹配

在真实语义中,人们通常不会认为<代码> CAFE <代码>是代码> CAFE的子串;

e
e
被视为不同的字符。
恰好表示为以
e
开头的一对字符,这是编码方案(Unicode)的内部实现细节,不应影响结果。上面的例子对比了
café
caf́
,说明了这一点;除非特别打算进行顺序(逐字节)比较,否则不会出现不同的结果

根据您的示例调整此解释:

var line1 = "café";   // 63 61 66 E9     – precomposed character 'é' (U+00E9)
var line2 = "café";   // 63 61 66 65 301 – base letter e (U+0065) and
                      //                   combining acute accent (U+0301)
var sub   = "cafe";   // 63 61 66 65 
Console.WriteLine(line1.StartsWith(sub));                             // false
Console.WriteLine(line2.StartsWith(sub));                             // false
Console.WriteLine(line1.StartsWith(sub, StringComparison.Ordinal));   // false
Console.WriteLine(line2.StartsWith(sub, StringComparison.Ordinal));   // true
string line = "Mìng-dĕ̤ng-ngṳ̄";   // 4D EC 6E 67 2D 64 115 324 6E 67 2D 6E 67 1E73 304
string sub  = "Mìng-dĕ̤ng-ngṳ";   // 4D EC 6E 67 2D 64 115 324 6E 67 2D 6E 67 1E73

每个.NET字符表示一个UTF-16代码单元,其值显示在上面的注释中。前14个代码单元是相同的,这就是为什么逐字符比较的结果为true(就像
StringComparison.Ordinal
)。但是,
中的第15个代码单元是组合宏单元,◌̄(),它与前面的
()给出
ṳ̄

这不是一个bug。实际上,
String.StartsWith
比仅仅逐个字符检查两个字符串要聪明得多。它考虑到了你当前的文化(语言设置等),也考虑了缩略语和特殊字符。(这并不重要,您需要两个字符才能以
ṳ̄
。它将其作为一个进行比较)

这意味着,如果您不想采用所有特定于区域性的设置,只想使用顺序比较进行检查,那么您必须告诉比较器

这是正确的方法(不要像以前那样忽略案例!):


使用不变的区域性。比如说,我不懂越南语。在最后一个“u”上有一条线。这不是一个不同的字母吗?编辑:我错过了你正在打印的长度,这似乎表明该行被视为另一个字符。。。有趣的是,在我看来,
StartsWith()
应该返回false,因为(正如乔纳森指出的),
line
实际上并不是以
sub
开头的@matthewswatson:也许,也许不是。你真的需要一个说越南语的人来决定这一点(我认为,即使在这个群体中,你也可以为这两种情况进行辩论。在我看来,这就像德语中的ävs a vs ae——答案只能是:这取决于……)@Thilo不,这真的不同。最后一个
u
是一个不同的字母。另外,要查看真正的长度,您需要使用
new StringInfo(line).lengthinetextrements
,它返回13,而不是字符串.length返回的15。但是StartsWith的默认比较器是什么?还有,为什么要使用IgnoreCase而不仅仅是序数?作者在不忽略大小写的情况下使用顺序比较。@VadimMartynov:我已将示例更新为使用
ordinal
。扩展解释。还值得注意的是,
line1.StartsWith(line2)
是正确的(反之亦然),
line1.Equals(line2,StringComparison.InvariantCulture)
[对于最合理的设置,CurrentCulture…单参数Equals似乎使用序数]但是为什么不考虑这些特定于文化的设置呢?我不会说越南语,这两个字符串是否应该被视为前缀相等?也就是说,OP。我也不知道越南,但我可以理解,有时你想用一种方式和下一次用另一种方式进行比较。这就是为什么你可以使用
序数
来影响比较。我理解。我想说的是,OP应该仔细考虑这是不是真的要走。我不认为这是一个文化特定的问题。在任何地方,它们都不会被认为是相同的。@ Thilo,你会说英语或其他欧洲语言吗?在这些语言中,人们通常将字母和变音符号视为一个单位,但也有少数例外(大多数例外是将字母组合起来,而不是将它们分开)。我们通常会说,
naive
naỉve
都有5个字母,
façade
façade
都有6个字母。NET相应地考虑了前两个到
的起始点彼此
,以及后两个,但相应地给出了
长度
的5、6、6和7。
string line = "Mìng-dĕ̤ng-ngṳ̄";   // 4D EC 6E 67 2D 64 115 324 6E 67 2D 6E 67 1E73 304
string sub  = "Mìng-dĕ̤ng-ngṳ";   // 4D EC 6E 67 2D 64 115 324 6E 67 2D 6E 67 1E73
line.StartsWith(sub, StringComparison.Ordinal);