Подтвердить что ты не робот

Каков правильный способ сравнения char игнорирующего случая?

Мне интересно, какой правильный способ сравнить два персонажа, игнорируя случай, который будет работать для всех культур. Кроме того, Comparer<char>.Default лучший способ проверить два символа без игнорирования случая? Это работает для суррогатных пар?

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()));
4b9b3361

Ответ 1

Это зависит от того, что вы подразумеваете под "работой для всех культур". Хотели бы вы, чтобы "я" и "я" были равны даже в Турции?

Вы можете использовать:

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

... но я не уверен, что "работает" по всем культурам по вашему пониманию "работ".

Конечно, вы можете преобразовать оба символа в строки, а затем выполнить любое сравнение, которое вы хотите в строках. Несколько менее эффективный, но он дает вам весь диапазон сравнений, доступных в рамках:

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

Для суррогатных пар a Comparer<char> в любом случае не будет выполнимо, потому что у вас нет ни одного char. Вы могли бы создать Comparer<int>, хотя.

Ответ 2

Используя стандартную (т.е. не) инвариантную):

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

Или укажите культуру:

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

Ответ 3

Как я понимаю, на самом деле не существует способа, который "будет работать для всех культур". Либо вы хотите сравнить символы для какой-то внутренней причины, а не для отображения для пользователя (в этом случае вы должны использовать InvariantCulture), или вы хотите использовать CurrentCulture для пользователя. Очевидно, что использование текущей культуры пользователя будет означать, что вы получите разные результаты в разных локалях, но они будут соответствовать ожиданиям пользователей в этих локалях.

Не зная больше о том, ПОЧЕМУ вы сравниваете двух символов, я не могу вам советовать, на каком из них вы должны использовать.

Ответ 4

string.Compare( "string a", "STRING A", true)

Он будет работать для каждой строки

Ответ 5

Вы можете попробовать:

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

Но я сомневаюсь, что это "оптимальный" способ сделать это, но я не все, что вам нужно проверять...

Ответ 6

То, что я думал, что будет доступно во время выполнения, выглядит следующим образом

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()));

Ответ 7

Я бы рекомендовал сравнить прописные буквы, и если они не совпадают, то сравнение строчных букв, на всякий случай, если верхняя и нижняя регионы локали отличаются друг от друга.

Добавление

Например,

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;
}