Wie kann ich einen String-Vergleich ohne Berücksichtigung der Groß- und Kleinschreibung durchführen?

217

Wie kann ich die Zeile unter Groß- und Kleinschreibung nicht berücksichtigen?

drUser["Enrolled"] = 
      (enrolledUsers.FindIndex(x => x.Username == (string)drUser["Username"]) != -1);

Ich habe heute früher einige Ratschläge erhalten, die mir vorschlugen, Folgendes zu verwenden:

x.Username.Equals((string)drUser["Username"], StringComparison.OrdinalIgnoreCase)));

Das Problem ist, dass ich dies nicht zum Laufen bringen kann. Ich habe die folgende Zeile ausprobiert. Diese wird kompiliert, gibt jedoch die falschen Ergebnisse zurück. Sie gibt registrierte Benutzer als nicht registrierte und nicht registrierte Benutzer als registrierte Benutzer zurück.

drUser["Enrolled"] = 
      (enrolledUsers.FindIndex(x => x.Username.Equals((string)drUser["Username"], 
                                 StringComparison.OrdinalIgnoreCase)));

Kann jemand auf das Problem hinweisen?

Jamie
quelle
1
Welcher Datentyp sollte drUser["Enrolled"]sein? Es sieht aus wie ein boolescher Wert, gibt aber FindIndex()den Index zurück. Wenn der Index dieses Benutzers 0 ist, wird 0 zurückgegeben, was möglicherweise falsch ist. Wann ist in Wirklichkeit wahr? Die Exists()Methode kann in diesem Fall besser sein.
Drharris
Sind Sie sicher, dass in einem Feld keine Zeit zum Formatieren oder ein zusätzlicher Speicherplatz vorhanden ist, der sich nicht im anderen befindet?
Joshlrogers
1
Ich würde vorschlagen, registrierte Benutzer.Any () anstelle von FindIndex (und Test) zu verwenden.
Marc

Antworten:

405

Dies ist nicht die beste Vorgehensweise in .NET Framework (4 & +), um die Gleichheit zu überprüfen

String.Compare(x.Username, (string)drUser["Username"], 
                  StringComparison.OrdinalIgnoreCase) == 0

Verwenden Sie stattdessen Folgendes

String.Equals(x.Username, (string)drUser["Username"], 
                   StringComparison.OrdinalIgnoreCase) 

MSDN empfiehlt:

  • Verwenden Sie eine Überladung der String.Equals-Methode, um zu testen, ob zwei Zeichenfolgen gleich sind.
  • Verwenden Sie die Methoden String.Compare und String.CompareTo , um Zeichenfolgen zu sortieren und nicht auf Gleichheit zu prüfen .
ocean4dream
quelle
8
Sie sollten string.Comparenicht verwenden String.Compare.
Fred
5
@Fred Ich stimme zu, aber können Sie den Grund qualifizieren?
Gusdor
22
@Fred Ich hatte eher auf einen technischen Grund gehofft als auf "weil Stylecop es sagt". Vermisse ich etwas
Gusdor
12
kein Unterschied string.compare mit String.Compare, String-Synonyme System.String-Klasse. und Mitglied Vergleich ist eine Erweiterungsmethode. @ Fred @ Gusdor
Nuri YILMAZ
23
@Gusdor stringist eine bessere Übung als Stringda es sich um ein Sprachschlüsselwort handelt. Zum einen Stringkönnte es etwas anderes sein als System.String, während stringes nicht sein kann. Außerdem stringist mehr oder weniger garantiert, dass es in C # existiert, wohingegen Stringes technisch eher Teil von .NET als von C # ist.
Dave Cousineau
36

Sie sollten die statische String.CompareFunktion wie folgt verwenden

x => String.Compare (x.Username, (string)drUser["Username"],
                     StringComparison.OrdinalIgnoreCase) == 0
Oleg
quelle
6
Nein, sollten Sie String.Equalsanstelle von verwenden String.Compare. Es ist nicht nötig zu berechnen, welches größer ist, nur dass sie nicht gleich sind.
ErikE
@ErikE: Ich frage mich, welche Methode Sie in weiteren 6 Jahren empfehlen werden :-)
Oleg
3
Ich wundere mich nicht! Ich bin zuversichtlich, dass ich die Verwendung von Gleichheit empfehlen werde, wenn Sie Gleichheitssemantik wünschen, und Vergleich, wenn Sie Vergleichssemantik wünschen. Was ist daran so schwierig? IEquatableund IComparabletun Sie NICHT dasselbe, und Sie können Klassen haben, die eine implementieren, in denen es jedoch KEINEN Sinn macht, die andere zu implementieren. Sie können beispielsweise Sensorabtastungen nach Zeit sortieren, ohne dass sie gleich sind (IComparable). Sie können angeben, ob die Dinge gleich sind (IEquatable), aber es macht keinen Sinn, sie zu bestellen (z. B. Computer-Seriennummern).
ErikE
@ErikE: Du verstehst meinen Standpunkt nicht. Alte Antworten entsprechen dem Zeitpunkt des Schreibens. Man sollte alte Antworten nicht anfassen. Es gilt für die meisten Produkte. Die Best Practice oder die beste Wahl aus Sicht der Leistung kann später mehrmals geändert werden. Ich sehe keinen Sinn, über eine alte Antwort zu diskutieren.
Oleg
18
Ich entschuldige mich und habe es als Kritik an der Richtigkeit meines Kommentars verstanden. Wenn Sie sagen, dass Sie zugeben, dass Ihre alte Antwort möglicherweise nicht die beste ist, dann großartig! Ich muss Ihnen jedoch in Bezug auf alte Antworten nicht zustimmen. Alte Antworten, die schlechte Informationen liefern, sollten kommentiert und abgelehnt werden, da sie die heutigen Leser immer noch informieren .
ErikE
27

Bitte verwenden Sie dies zum Vergleich:

string.Equals(a, b, StringComparison.CurrentCultureIgnoreCase);
Gautam Kumar Sahu
quelle
10
Beachten Sie nur die Vor- und Nachteile der Verwendung von CurrentCultureIgnoreCase im Vergleich zu OrdinalIgnoreCase. Wenn Sie die Semantik des Kulturvergleichs nicht benötigen, sparen Sie etwas Leistung und verwenden Sie den Ordnungsvergleich.
ErikE
7

Andere Antworten sind hier völlig gültig, aber irgendwie dauert es einige Zeit, sie zu tippen StringComparison.OrdinalIgnoreCaseund auch zu verwenden String.Compare.

Ich habe eine einfache String-Erweiterungsmethode codiert, bei der Sie angeben können, ob beim Vergleich zwischen Groß- und Kleinschreibung unterschieden wird oder ob die Groß- und Kleinschreibung nicht berücksichtigt wird. Fügen Sie hier das gesamte Code-Snippet hinzu:

using System;

/// <summary>
/// String helpers.
/// </summary>
public static class StringExtensions
{
    /// <summary>
    /// Compares two strings, set ignoreCase to true to ignore case comparison ('A' == 'a')
    /// </summary>
    public static bool CompareTo(this string strA, string strB, bool ignoreCase)
    {
        return String.Compare(strA, strB, ignoreCase) == 0;
    }
}

Danach verkürzt sich der gesamte Vergleich um ungefähr 10 Zeichen - vergleiche:

Vor der Verwendung der String-Erweiterung:

String.Compare(testFilename, testToStart,true) != 0

Nach Verwendung der String-Erweiterung:

testFilename.CompareTo(testToStart, true)
TarmoPikaro
quelle
2
Ich bin mit der Benennung nicht einverstanden, vergleiche ist eine bekannte Funktion in der Softwareentwicklung und Sie haben grundlegend geändert, was sie tut. Ich denke, Sie sollten entweder ein int wie compare zurückgeben oder den Namen in etwas anderes ändern, zum Beispiel 'IsEqual'.
Fred
7

Sie können (obwohl kontrovers) erweitern System.String, um eine Methode zur Erweiterung des Vergleichs ohne Berücksichtigung der Groß- und Kleinschreibung bereitzustellen:

public static bool CIEquals(this String a, String b) {
    return a.Equals(b, StringComparison.CurrentCultureIgnoreCase);
}

und als solche verwenden:

x.Username.CIEquals((string)drUser["Username"]);

Mit C # können Sie Erweiterungsmethoden erstellen, die in Ihrem Projekt als Syntaxzucker dienen können. Dies ist sehr nützlich, würde ich sagen.

Es ist nicht die Antwort und ich weiß, dass diese Frage alt und gelöst ist. Ich wollte nur diese Teile hinzufügen.

Felype
quelle
3

Ich denke, Sie finden weitere Informationen in diesem Link:

http://codeidol.com/community/dotnet/controlling-case-sensitivity-when-comparing-two-st/8873/

Verwenden Sie die statische Methode Compare für die String-Klasse, um die beiden Strings zu vergleichen. Ob der Vergleich nicht zwischen Groß- und Kleinschreibung unterscheidet, wird durch den dritten Parameter einer seiner Überlastungen bestimmt. Beispielsweise:

string lowerCase = "abc";
string upperCase = "AbC";
int caseInsensitiveResult = string.Compare(lowerCase, upperCase,
  StringComparison.CurrentCultureIgnoreCase);
int caseSensitiveResult = string.Compare(lowerCase,
  StringComparison.CurrentCulture);

Der caseSensitiveResult-Wert ist -1 (zeigt an, dass lowerCase "kleiner als" UpperCase ist) und caseInsensitiveResult ist Null (zeigt an, dass lowerCase "gleich" UpperCase ist).

i_thamary
quelle
1

Ich möchte eine Erweiterungsmethode für EqualsIgnoreCase schreiben

public static class StringExtensions
{
    public static bool? EqualsIgnoreCase(this string strA, string strB)
    {
        return strA?.Equals(strB, StringComparison.CurrentCultureIgnoreCase);
    }
}
Ranga
quelle
-11

Sie können immer folgende Funktionen verwenden: .ToLower (); .ToUpper ();

konvertiere deine Strings und vergleiche sie dann ...

Viel Glück

user3895427
quelle
Ich glaube nicht, dass dies sein Problem lösen würde. Markieren Sie auch, dass diese Frage bereits älter als 4 Jahre ist.
Vojtěch Dohnal
7
Dadurch wird eine neue Zeichenfolge erstellt, daher halte ich dies für sehr ineffizient. Da zum Erstellen dieser neuen Zeichenfolge alle Zeichen überprüft und in den gewünschten Fall konvertiert werden, muss der Vergleich alle Zeichen erneut überprüfen. Es verbraucht also mehr Speicher und Rechenleistung.
Air2
5
Dies ist aufgrund der Speicherzuweisung sehr schlecht.
Thorbjørn Lindeijer
Dies ist nicht nur eine unnötige Speicherzuweisung und ineffizient. es besteht auch den Türkei-Test nicht .
dmitry