なぜstring.Compareは矛盾アクセント付き文字を扱うように見えるのでしょうか?
-
21-09-2019 - |
質問
私は次の文を実行した場合:
string.Compare("mun", "mün", true, CultureInfo.InvariantCulture)
結果は「-1」、「MUNが「ムン」よりも低い数値を有することを示す。
しかし、私はこの文を実行する場合:
string.Compare("Muntelier, Schweiz", "München, Deutschland", true, CultureInfo.InvariantCulture)
私は 'ムンテリアー、Schewizは' 最後に行くべきであることを示し、 '1' を取得しています。
これは比較のバグですか?または、より多くの可能性が高い、アクセント付き
を含む文字列をソートするとき、私は考慮に入れてしなければならないルールがあります <時間>これが問題である理由は、私は、リストをソートして、「XXX」で始まるすべての文字列を取得するためのものだマニュアルバイナリフィルタをやっている、である。
以前、私は「どこに」メソッドにLINQを使用していたが、彼はそれがより良い実行言うので、今私は、別の人によって書かれたこのカスタム関数を使用する必要があります。
しかし、カスタム関数は、アカウントに.NETが持っているものは何でも「ユニコード」のルールを取るようには見えません。私は「ムン」でフィルタにそれを伝えるのであれば、それは「ムン」で始まる、リスト内の項目があるにもかかわらず、任意の項目を見つけることができません。
この文字は、アクセント付き文字の後に行くものに応じて、ためにアクセント付き文字の一貫性のない順序であるように思われる。
<時間>OK、私は問題を修正したと思う。
フィルタの前に、私はのN の各文字列の最初ののN の文字は検索文字列の長さです。
に基づいて並べ替えを行います解決
仕事でタイブレークアルゴリズムがあり、 http://unicode.org/reports/tr10/を見ますの
の複雑さに対処するには、言語に依存するソート、A マルチレベルの比較アルゴリズムがあります 雇用された。以下のために、二つの単語を比較すると たとえば、最も重要な特徴は、 基本文字:など AとBとの間の差 アクセントの違いは、典型的には どんな違いがある場合は、無視 ベース手紙インチケースの違い (大文字対小文字)であります もしあれば、通常、無視 ベースやアクセントの違い。 句読点は可変です。一部で 句読点文字がある状況 基本文字のように扱わ。に 他の状況では、それは無視されなければなりません 任意の塩基、アクセント、またはケースがある場合 違い。またあるかもしれません 最終的な、タイブレークレベル、それによってもし 全く他の違いはありません 文字列内の、(正規化)コード ポイントの順序が使用されます。
だから、 "Munt ..." と "Münc..." アルファベット順に異なるとソート "T" と "C" に基づいている。
文字コードが比較されるように、、「MUN」および「MUN」に対しアルファベット同じ(失われた言語で「U」を「U」equivelent)である
他のヒント
アクセント付き文字のみ「タイブレーク」状況の一種で使用されているように見えます - 。文字列がそう等しい場合、つまり
ここに証明するためにいくつかのサンプルコードです:
using System;
using System.Globalization;
class Test
{
static void Main()
{
Compare("mun", "mün");
Compare("muna", "münb");
Compare("munb", "müna");
}
static void Compare(string x, string y)
{
int result = string.Compare(x, y, true,
CultureInfo.InvariantCulture));
Console.WriteLine("{0}; {1}; {2}", x, y, result);
}
}
(私はそれがワード境界に行われたかどうかを確認するために、「n」は、同様の後にスペースを追加しようとしました - 。それはありません)。
結果:
mun; mün; -1
muna; münb; -1
munb; müna; 1
私はこれは、さまざまな複雑なUnicodeのルールにより、正確である疑いがある - 。しかし、私はそれらについて十分に知らない
あなたはこれを考慮に入れる必要があるかどうかについては...私はそう期待していません。あなたはそれが、このによってスローされた何をしているのか?
それはまだ多少一貫しています。 CultureInfo.InvariantCulture
を使用して比較した場合ウムラウト文字ü
は、非アクセント付き文字u
のように扱われています。
あなたの最初の例では、文字列は明らかに結果が0ではありません等しくないとしてではなく、-1(デフォルト値であるように思われます)。 2番目の例では、のムンテリアーののT はアルファベットでのC のを以下のため。
最後に行きます私は、これらのルールを説明するMSDNでの明確なドキュメントを見つけることができませんでしたが、私は
ことがわかりましたstring.Compare("mun", "mün", CultureInfo.InvariantCulture,
CompareOptions.StringSort);
と
string.Compare("Muntelier, Schweiz", "München, Deutschland",
CultureInfo.InvariantCulture, CompareOptions.StringSort);
は、所望の結果を与えます。
とにかく、私はあなたが(可能な場合)など、現在のユーザーの文化として、特定の文化に並べ替えベースに、より良いオフだろうと考えています。