2014-12-15 10 views
8

Mein Problem ist, dass String.IndexOf-1 zurückgibt. Ich würde erwarten, dass es 0 zurückgibt.IndexOf und ordinale Zeichenfolgenvergleiche

Die Parameter:

text = C:\\Users\\User\\Desktop\\Sync\\̼ (beachten Sie die Combining Seagull Below Zeichen)

stringToTrim = C:\\Users\\User\\Desktop\\Sync\\

Wenn ich für den Index zu überprüfen, mit int index = text.IndexOf(stringToTrim);, ist der Wert von index-1. Ich fand, dass ein Ordnungs String-Vergleich unter Verwendung dieses Problem von mir gelöst:

int index = text.IndexOf(stringToTrim, StringComparison.Ordinal); 

Online-Lese, eine Menge von Unicode-Zeichen (wie U+00B5 und U+03BC) Karte mit dem gleichen Symbol, so wäre es eine gute Idee sein, zu erweitern und normalisieren beide Strings:

int index = text.Normalize(NormalizationForm.FormKD).IndexOf(stringToTrim.Normalize(NormalizationForm.FormKD), StringComparison.Ordinal); 

Ist dies der richtige Ansatz, um zu überprüfen, bei welchem ​​Index eine Zeichenfolge alle aufeinander folgenden Zeichen einer anderen Zeichenfolge enthält? Die Idee ist also, dass Sie normalisieren, wenn Sie überprüfen wollen, ob Symbole übereinstimmen, aber Sie normalisieren sich nicht, wenn Sie Zeichen anhand ihrer codierten Werte überprüfen möchten (also doppelte Symbole zulassen)? Könnte auch jemand bitte erklären, warum int index = text.IndexOf(stringToTrim); am Anfang der Zeichenfolge keine Übereinstimmung gefunden hat? Mit anderen Worten, was macht es tatsächlich unter den Deckungen? Ich hätte erwartet, dass es beginnt, Zeichen vom Anfang der Zeichenfolge bis zum Ende der Zeichenfolge zu suchen.

+0

I/diese in LinqPad eingefügt kopiert und bekam „0“ zurück - vielleicht verstehe ich nicht die Kombination von Zeichen. – dnord

+0

@dnord Versuchen Sie Folgendes: '" C: \\ Benutzer \\ Benutzer \\ Desktop \\ Sync \\ ".IndexOf (" C: \\ Benutzer \\ Benutzer \\ Desktop \\ Sync \\ ");' Achte darauf, diesen Text vollständig/genau von hier zu kopieren! – Alexandru

+0

(Danke, das funktioniert hat.) Dann stimme ich der Antwort des Top-Raters zu: entweder kombinierende Charaktere ändern das vorherige Zeichen (durch Kombination) oder Sie haben einen seltsamen Fehler gefunden, vor dem Sie zumindest von Microsoft gewarnt wurden. – dnord

Antwort

6

Das Verhalten macht für mich vollkommen Sinn. Sie verwenden ein kombinierendes Zeichen, das kombiniert mit dem vorhergehenden Zeichen ist, und verwandelt es in ein anderes Zeichen, das nicht mit dem Zeichen '\\' übereinstimmt, das Sie am Ende der Suchzeichenfolge angegeben haben. Dadurch wird verhindert, dass die gesuchte Zeichenfolge gefunden wird. Wenn Sie stattdessen nach "C:\\Users\\User\\Desktop\\Sync" gesucht hätten, hätte es gefunden.

Mit StringComparison.Ordinal wird .NET angewiesen, die verschiedenen Regeln für Zeichen zu ignorieren und nur auf ihren genauen Ordnungswert zu achten. Das scheint zu tun, was du wolltest, also ja, verdammt, das solltest du tun.

Der "richtige Ansatz" hängt ganz davon ab, welches Verhalten Sie wollen. Eine große Anzahl von String-Manipulationen beinhaltet, dass Text dem Benutzer präsentiert wird oder von ihm bereitgestellt wird und in einer kulturbewussten und Unicode-bewussten Weise ausgeführt werden sollte. Zu anderen Zeiten ist das nicht wünschenswert. Es ist wichtig, den richtigen Ansatz für Ihre Bedürfnisse auszuwählen.

1

Ja, Sie sollten StringComparison.Ordinal verwenden, um zu garantieren, dass die Kultur ignoriert wird, wenn Sie den Wert vergleichen. Dies ist besonders für alle Strings notwendig, die standardmäßig "kulturinvariant" sind. Das schließt Dateipfade ein.

Wenn nicht StringComparison.Ordinal verwendet) ist es möglich, geringfügige Fehler vorstellen: http://msdn.microsoft.com/en-us/library/dd465121(v=vs.110).aspx

Wenn kulturell unabhängige String-Daten, wie zum Beispiel XML-Tags, HTML-Tags, Benutzername, Dateipfade, und die Namen des Systems Objekte, sind interpretiert, als ob sie kultursensibel waren, kann der Anwendungscode unterliegen subtile Bugs, schlechte Leistung und in einigen Fällen Sicherheit Probleme.

Einige Nebeneffekt StringComparison.Ordinal ist eine bessere Leistung: http://msdn.microsoft.com/en-us/library/ms973919.aspx