Wat is de juiste manier om char te vergelijken waarbij hoofdletters worden genegeerd?

Ik vraag me af wat de juiste manier is om twee karakters te vergelijken, waarbij hoofdletters worden genegeerd, wat voor alle culturen werkt. Is Comparer<char>.Defaultook de beste manier om twee tekens te testen zonder hoofdletters te negeren? Werkt dit voor surrogaatparen?

EDIT: voorbeeld van IComparer<char>-implementatie toegevoegd

Als dit iemand helpt, is dit wat ik heb besloten te gebruiken

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

Antwoord 1, autoriteit 100%

Het hangt ervan af wat je bedoelt met “werken voor alle culturen”. Zou je willen dat “i” en “I” gelijk zijn, zelfs in Turkije?

Je zou kunnen gebruiken:

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

… maar ik weet niet zeker of dat “werkt” volgens alle culturen door uw begrip van “werkt”.

Natuurlijk kunt u beide tekens converteren naar tekenreeksen en vervolgens de gewenste vergelijking op de tekenreeksen uitvoeren. Iets minder efficiënt, maar het geeft je wel alle beschikbare vergelijkingen in het raamwerk:

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

Voor surrogaatparen is een Comparer<char>sowieso niet haalbaar, omdat je geen enkele charhebt. Je zou echter een Comparer<int>kunnen maken.


Antwoord 2, autoriteit 2%

Zoals ik het begrijp, is er niet echt een manier die “voor alle culturen werkt”. Of je wilt karakters vergelijken om een ​​of andere interne reden die niet aan de gebruiker wordt weergegeven (in dat geval moet je de InvariantCulture gebruiken), of je wilt de CurrentCulture van de gebruiker gebruiken. Het is duidelijk dat het gebruik van de huidige cultuur van de gebruiker betekent dat u verschillende resultaten krijgt in verschillende landen, maar ze zullen consistent zijn met wat uw gebruikers in die landen zullen verwachten.

Zonder meer te weten over WAAROM je twee karakters vergelijkt, kan ik je niet echt adviseren over welke je zou moeten gebruiken.


Antwoord 3

Ik raad aan om hoofdletters te vergelijken, en als ze niet overeenkomen, vergelijk dan kleine letters, voor het geval de hoofdletters en kleine letters van de landinstelling zich iets anders gedragen.

Aanvulling

Bijvoorbeeld

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

Antwoord 4

Wat ik dacht dat binnen de runtime beschikbaar zou zijn, is zoiets als het volgende

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

Antwoord 5

string.Compare(“string a”,”STRING A”,true)

Het werkt voor elke string


Antwoord 6

je zou kunnen proberen:

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

Maar ik betwijfel of dit de “optimale” manier is om het te doen, maar ik ben niet alle gevallen die u moet controleren …


Antwoord 7

Ik weet dat dit een oude post is, maar de dingen zijn sindsdien veranderd.

De bovenstaande vraag kan worden beantwoord met behulp van een extensie. Dit zou de Char.equals verlengen om plaats te bieden aan plaats en case-ongevoeligheid.

Voeg in een verlengingsklasse iets toe, zoals:

internal static Boolean Equals(this Char src, Char ch, StringComparison comp)
{
    Return $"{src}".Equals($"{ch}", comp);
}

Ik ben momenteel aan het werk, dus kan dit niet controleren, maar het zou moeten werken.

Andy


Antwoord 8

U kunt het laatste argument voor caseinsensetive-match

aanbieden

string.Compare(lowerCase, upperCase, true);

Other episodes