Wie mache ich eine groß-und Kleinschreibung string-Vergleich?
Wie kann ich tun, groß-und Kleinschreibung string-Vergleich in Python?
Ich würde gerne Kapseln Vergleich: eine reguläre Zeichenfolgen, um eine repository-string in eine sehr einfache und Pythonic way. Ich möchte auch die Möglichkeit haben, zu suchen, bis die Werte in einem dict-Hash von strings mit regulären python-strings.
InformationsquelleAutor Kozyarchuk | 2008-11-26
Du musst angemeldet sein, um einen Kommentar abzugeben.
Vorausgesetzt ASCII-strings:
Σίσυφος
undΣΊΣΥΦΟΣ
, dann ist dein Ansatz fehl, da diese angeblich der gleiche Fall unempfindlich.Die beiden letzten Kommentatoren: ich denke, es ist fair zu übernehmen, beide strings sind ascii-strings. Wenn Sie auf der Suche nach einer Antwort auf etwas ein bisschen spannender, ich bin sicher, es gibt (oder die man Fragen kann).
Problem:
'ß'.lower() == 'SS'.lower()
ist Falsch.Griechische Buchstaben ist nicht der einzige Besondere Fall! In US-Englisch, das Zeichen "i" (\u0069) ist die Kleinbuchstaben version des Zeichens "I" (\u0049). Aber die türkischen ("tr-TR") alphabet enthält ein "I mit Punkt" Charakter "I" (\u0130), ist die Großschreibung von "ich" und "ich" ist die captical version von "i ohne Punkt" Charakter, "ı" (\u0131).
wie ist es sicher (oder fair) davon ausgehen, dass die strings sind ascii? Die Frage wurde nicht angegeben, und wenn die Saiten an jedem Punkt eingegeben oder die Karte an einen Benutzer, dann sollten Sie die Unterstützung von Internationalisierung. Egal, neue Programmierer wird dies Lesen, und wir sollten Ihnen die wirklich richtige Antwort.
InformationsquelleAutor Harley Holcombe
Vergleich von Zeichenfolgen in groß-und Kleinschreibung Weg scheint wie etwas, das ist trivial, aber es ist nicht. Ich werde mich mit Python 3, da Python 2 ist unterentwickelt hier.
Ist die erste Sache, zu beachten, dass Fall-entfernen im unicode-Konvertierungen sind nicht trivial. Es ist der text für die
text.lower() != text.upper().lower()
wie"ß"
:Aber lassen Sie uns sagen, Sie wollten caselessly vergleichen
"BUSSE"
und"Buße"
. Heck, Sie wahrscheinlich wollen auch vergleichen"BUSSE"
und"BUẞE"
gleich - das ist die neuere Kapitals bilden. Der empfohlene Weg ist die Verwendungcasefold
:Nicht
lower
. Wenncasefold
ist nicht verfügbar, tut.upper().lower()
hilft (aber nur etwas).Dann sollten Sie Akzente. Wenn Ihr font-renderer ist gut, denken Sie wahrscheinlich
"ê" == "ê"
- muss es aber nicht:Dies ist, weil Sie eigentlich
Die einfachste Möglichkeit, damit umzugehen, ist
unicodedata.normalize
. Sie wollen wahrscheinlich verwenden NFKD Normalisierung, aber fühlen Sie sich frei, um die Dokumentation zu kontrollieren. Dann tut manZu beenden, ist dies hier ausgedrückt in Funktionen:
x.casefold() == y.casefold()
für groß-und Kleinschreibung Vergleiche (und, noch wichtiger,x == y
für groß- / Kleinschreibung).In der Tat, je nach Kontext, manchmal ist es besser zu verlassen, die Quelle intakt, aber im Voraus Normalisierung kann auch später-code viel einfacher.
Du hast Recht, es ist nicht immer angebracht; wenn Sie brauchen, um in der Lage sein, um die Ausgabe der original-Quelle, unverändert (z.B., weil Ihnen der Umgang mit Dateinamen unter Linux, wo NKFC und NKFD sind beide erlaubt und ausdrücklich soll anders sein), natürlich kannst du nicht transformieren, das auf input...
Unicode-Standard, Abschnitt 3.13 hat zwei andere Definitionen für caseless comparisons: (D146, kanonische)
NFD(toCasefold(NFD(str)))
auf beiden Seiten und (D147, Kompatibilität)NFKD(toCasefold(NFKD(toCasefold(NFD(X)))))
auf beiden Seiten. Es heißt, die innereNFD
ist ausschließlich auf eine bestimmte Griechische Akzent. Ich denke, es ist alles über die Grenzfälle.Und ein bisschen Spaß haben mit dem Cherokee-alphabet, wo casefold() geht Großbuchstaben:>>> "ᏚᎢᎵᎬᎢᎬᏒ".upper() 'ᏚᎢᎵᎬᎢᎬᏒ' >>> "ᏚᎢᎵᎬᎢᎬᏒ".lower() 'ꮪꭲꮅꭼꭲꭼꮢ' >>> "ᏚᎢᎵᎬᎢᎬᏒ".casefold() 'ᏚᎢᎵᎬᎢᎬᏒ' >>>
InformationsquelleAutor Veedrac
Mit Python 2, Aufruf
.lower()
auf alle string-oder Unicode-Objekt......wird die meiste Zeit funktionieren, aber in der Tat nicht die Arbeit in der Situationen, @tchrist beschrieben hat.
Angenommen, wir haben eine Datei namens
unicode.txt
mit den zwei SaitenΣίσυφος
undΣΊΣΥΦΟΣ
. Mit Python 2:Dem Σ-Zeichen hat zwei kleine Formen, ς und σ, und
.lower()
wird nicht helfen, vergleichen Sie Sie Fall-unempfindlich.Jedoch, wie der Python 3, alle drei Formen aufgelöst wird, ς, und das untere() auf beide strings korrekt funktioniert:
Also wenn Sie um den Rand-Fällen, wie bei den drei sigmas in der griechischen, verwenden Python 3.
(Für Referenz, Python 2.7.3 und Python 3.3.0b1 gezeigt, sind in der interpreter-Ausdrucke oben).
InformationsquelleAutor Nathan Craike
Abschnitt 3.13 der Unicode-standard definiert-algorithmen für caseless
das matching.
X.casefold() == Y.casefold()
in Python 3 implementiert die "Standard-caseless matching" (D144).Casefolding nicht die Erhaltung der Normalisierung von strings, die in allen Instanzen und damit die Normalisierung durchgeführt werden muss (
'å'
vs.'å'
). D145 stellt das "kanonische caseless matching":NFD()
ist zweimal genannt, für sehr seltene Sonderfälle mit U+0345 Charakter.Beispiel:
Gibt es auch die Kompatibilität caseless matching (D146) für Fälle wie
'㎒'
(U+3392) und "Bezeichner caseless-matching" zu vereinfachen und zu optimieren caseless matching von Bezeichnern.Leider, wie der Python-3.6, die
casefold()
Funktion implementiert nicht den speziellen Fall der Behandlung von groß-ich und gepunktete groß-ich, wie beschrieben, in der Case Folding Eigenschaften. Also, der Vergleich mag nicht für Wörter, die aus türkischen Sprachen, enthalten diese Briefe. Zum Beispielcanonical_caseless('LİMANI') == canonical_caseless('limanı')
muss zurückTrue
, aber es gibtFalse
. Derzeit ist der einzige Weg, um sich mit diesem in Python zu schreiben casefold wrapper oder die Verwendung eines externen Unicode-Bibliothek, wie PyICU.verhält sich so, wie es sollte, soweit ich das sagen kann. Aus dem standard: "der Standard-Gehäuse-Operationen sind für den Gebrauch in der Abwesenheit der Schneiderei für bestimmte Sprachen und Umgebungen". Gehäuse Regeln für die Türkisch-gepunktete Kapital I und punktlosen kleine ich sind in SpecialCasing.txt. "Für nicht-türkischen Sprachen, diese Zuordnung ist in der Regel nicht." Von der Unicode-FAQ: Q: Warum gibt es keine extra-Zeichen codiert Unterstützung locale-unabhängigen Gehäuse für türkische?
Ich habe nicht gesagt, dass casefold() falsch verhält. Es wäre einfach praktisch, wenn es implementiert ein optionaler parameter, der aktiviert die spezielle Behandlung von groß-und gepunktete Großbuchstaben I. Zum Beispiel, die Art und Weise die foldCase() in der ICU-Bibliothek bietet it: "Case-folding locale-unabhängigen und nicht-Kontext-Sensitiv, aber es ist eine option für die, ob einschließen oder ausschließen Zuordnungen für punktierte ich und punktlosen ich, die markiert sind mit" T " in CaseFolding.txt."
InformationsquelleAutor jfs
Sah ich diese Lösung hier mit regex.
Klappt es auch mit Akzenten
Aber es funktioniert nicht mit unicode-Zeichen, die groß-und Kleinschreibung. Danke @Rhymoid für den Hinweis, das ist mein Verständnis war, dass es muss die genaue symbol, für den Fall, um wahr zu sein. Die Ausgabe ist wie folgt:
ß
ist nicht innerhalbSS
mit groß-und Kleinschreibung in Suche ist der Beweis, dass es funktioniert nicht arbeiten mit Unicode-Zeichen überhaupt.InformationsquelleAutor Shiwangi
Wie etwa die Umwandlung in Kleinbuchstaben zuerst? Sie können
string.lower()
.Σίσυφος
undΣΊΣΥΦΟΣ
würde nicht test gleichwertig, aber sollte.InformationsquelleAutor Camilo Díaz Repka
Ist die übliche Vorgehensweise ist zu groß-die Saiten-oder Kleinschreibung Sie für die Suchvorgänge und Vergleiche. Zum Beispiel:
InformationsquelleAutor Andru Luvisi
Dies ist ein weiterer regex, die ich habe gelernt zu lieben/hassen in der letzten Woche so in der Regel zu importieren (in diesem Fall) ja etwas, das widerspiegelt, wie im Gefühl!
eine normale Funktion.... Fragen für die Eingabe, dann verwenden ....etwas = re.compile(r'foo*|spam*', ja.I)...... re.Ich (ja.I unten) ist die gleiche wie IGNORECASE, aber man kann so viele Fehler zu schreiben!
Du dann suchen Sie Ihre Nachricht mithilfe von regex, aber ehrlich gesagt, sollte ein paar Seiten in seiner eigenen , aber der Punkt ist, dass foo oder spam geleitet zusammen und Kleinschreibung wird ignoriert.
Dann, wenn entweder gefunden, dann lost_n_found anzeigen würde einer von Ihnen. wenn weder dann lost_n_found ist gleich None. Wenn Ihr nicht gleich zu keiner Rückkehr der user_input in Kleinschreibung mit "return lost_n_found.lower()"
Dadurch können Sie viel leichter match-up alles, was thats gehen, um groß-und Kleinschreibung werden. Schließlich (NCS) steht für "niemand kümmert sich ernsthaft...!" - oder groß-und Kleinschreibung nicht....je nachdem, was
wenn jemand Fragen hat mich auf diesem..
InformationsquelleAutor Ali Paul
InformationsquelleAutor Patrick Harrington
Wenn Sie Listen mit strings und vergleichen Sie die Zeichenfolgen in andere Liste mit groß-und Kleinschreibung. Hier ist meine Lösung.
Nachdem Sie das getan, können Sie string-Vergleich easly.
InformationsquelleAutor caesar
Ich habe diese verwendet werden, um etwas zu erreichen mehr nützlich für den Vergleich von zwei strings:
Update: Wie bereits von gerrit, diese Antwort hat einige bugs. Das ist schon Jahre her ist und ich mich nicht mehr erinnern, was ich benutzt habe. Ich erinnere mich, dass das schreiben von tests, aber was sind Sie nun!
Diese Lösung versteckt bugs. Stell dir vor, wenn ich einen Fehler haben und zufälligerweise
strings_iequal("1", 1)
. Das Ergebnis wirdNone
. Allerdings, wenn ich den passstrings_iequal("", 0)
werden, ist das ErgebnisTrue
. Ich weiß nicht, was Sie wollen, zu erreichen mit der block innerhalb derexcept
-Teil.InformationsquelleAutor Chris