web-dev-qa-db-ja.com

大文字小文字を区別せずにcharを比較する正しい方法は何ですか?

すべての文化で機能する大文字と小文字を区別せずに2つの文字を比較する正しい方法は何だろうと思っています。も、また Comparer<char>.Default大文字小文字を無視せずに2文字をテストする最良の方法は?これはサロゲートペアに対して機能しますか?

[〜#〜] edit [〜#〜]:サンプルの追加IComparer<char>実装

これが誰かを助けるなら、これは私が使用することにしたものです

public class CaseInsensitiveCharComparer : IComparer<char> {
    private readonly System.Globalization.CultureInfo ci;
    public CaseInsensitiveCharComparer(System.Globalization.CultureInfo ci) {
        this.ci = ci;
    }
    public CaseInsensitiveCharComparer()
        : this(System.Globalization.CultureInfo.CurrentCulture) { }
    public int Compare(char x, char y) {
        return Char.ToUpper(x, ci) - Char.ToUpper(y, ci);
    }
}

// Prints 3
Console.WriteLine("This is a test".CountChars('t', new CaseInsensitiveCharComparer()));
47
Brett Ryan

「すべての文化のために働く」という意味に依存します。トルコでも「i」と「I」を等しくしたいですか?

次を使用できます。

bool equal = char.ToUpperInvariant(x) == char.ToUpperInvariant(y);

...しかし、「作品」を理解していれば、それがすべての文化に従って「作品」になっているかどうかはわかりません。

もちろん、両方の文字を文字列に変換してから、文字列に対して任意の比較を実行できます。効率はやや劣りますが、フレームワークで利用可能なすべての比較範囲が提供されます。

bool equal = x.ToString().Equals(y.ToString(), 
                                 StringComparison.InvariantCultureIgnoreCase);

サロゲートペアの場合、Comparer<char>は、単一のcharがないため、とにかく実行可能ではありません。ただし、Comparer<int>を作成できます。

80
Jon Skeet

デフォルト(つまりnot不変)カルチャを使用します。

if (char.ToLower(ch1) == char.ToLower(ch2))
{  ....  }

または、カルチャを指定します。

CultureInfo myCulture = ...;
if (char.ToLower(ch1, myCulture) == char.ToLower(ch2, myCulture))
{  ....  }
13
Henk Holterman

ランタイム内で利用できると思っていたのは、次のようなものです

public class CaseInsensitiveCharComparer : IComparer<char> {
    private readonly System.Globalization.CultureInfo ci;
    public CaseInsensitiveCharComparer(System.Globalization.CultureInfo ci) {
        this.ci = ci;
    }
    public CaseInsensitiveCharComparer()
        : this(System.Globalization.CultureInfo.CurrentCulture) { }
    public int Compare(char x, char y) {
        return Char.ToUpper(x, ci) - Char.ToUpper(y, ci);
    }
}

// Prints 3
Console.WriteLine("This is a test".CountChars('t', new CaseInsensitiveCharComparer()));
0
Brett Ryan

大文字を比較することをお勧めします。ロケールの大文字と小文字のロジックがわずかに異なる場合に備えて、大文字を比較し、小文字を比較することをお勧めします。

補遺

例えば、

int CompareChar(char c1, char c2)
{
    int  dif;

    dif = char.ToUpper(c1) - char.ToUpper(c2);
    if (diff != 0)
        dif = char.ToLower(c1) - char.ToLower(c2);
    return dif;
}
0
David R Tribble

あなたが試すことができます:

    class Test{
    static int Compare(char t, char p){
        return string.Compare(t.ToString(), p.ToString(), StringComparison.CurrentCultureIgnoreCase);
    }
}

しかし、私はこれがそれを行うための「最適な」方法であるとは思いませんが、私はあなたがチェックする必要があるすべてのケースではありません...

0
ahawker