StartsWith
によって返された結果は正しいです。デフォルトでは、ほとんどの文字列比較メソッドは、プレーンなバイトシーケンスではなく、現在のカルチャを使用してカルチャに敏感な比較を実行します。 line
は、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
上記の例では、line2
sub
と同じバイトシーケンスで始まり、最後にに適用される鋭いアクセント(U + 0301)の結合が続きます。 line1
はé
(U + 00E9)にprecomposed characterを使用しているため、そのバイトシーケンスはsub
のバイトシーケンスと一致しません。
実際には、cafe
はcafé
の部分文字列ではないと見なされます。 e
およびé
は異なる文字として扱われます。そのé
は、結果に影響を及ぼさないエンコードスキーム(Unicode)の内部実装の詳細であるe
で始まる一対の文字として表されます。これは、上記の例では、café
およびcafé
を対照として示されています。特に序数(バイト単位)の比較を意図しない限り、異なる結果を期待することはありません。あなたの例には、この説明を適応
:
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個のコード単位は同一であるため、char-by-charの比較はtrueと評価されます(ちょうどStringComparison.Ordinal
のように)。しかし、line
の15番目のコードユニットは、前のṳ
(U+1E73)と組み合わされてṳ̄
となる結合マクロン、◌̄(U+0304)です。
は、インバリアントカルチャを使用してください。例えば、http://stackoverflow.com/q/492799/1364007を参照してください。 –
私はベトナム語を知らない。最後の 'u'の上に線があります。それはそれを別の手紙にしませんか? *編集:*私は長さを印刷していることを忘れていました。これは、その行が別の*文字と見なされているようです。 –
'StartsWith()'がfalseを返すべきであると私には思われます。(Jonathonが指摘するように) 'line'は実際に' sub'で始まらないからです。 –