Porównywanie ciągów znaków bez rozróżniania wielkości liter wydaje się trywialne, ale nie jest. Będę używał Python 3, ponieważ Python 2 jest tutaj słabo rozwinięty.
Pierwszą rzeczą, na którą należy zwrócić uwagę, jest to, że konwersje z usuwaniem wielkości liter w Unicode nie są trywialne. Jest to tekst, dla którego text.lower() != text.upper().lower()
, jak "ß"
:
"ß".lower()
#>>> 'ß'
"ß".upper().lower()
#>>> 'ss'
Ale powiedzmy, że chciałeś bezmyślnie porównać "BUSSE"
i "Buße"
. Cholera, prawdopodobnie chcesz też porównać "BUSSE"
i "BUẞE"
zrównać się - to nowa forma kapitału. Zalecanym sposobem jest użycie casefold
:
str. casefold ()
Zwraca kopie łańcucha z kopertami. Ciągi z fałdowanymi literami mogą być używane do dopasowania bez case'ów.
Folderowanie jest podobne do tworzenia małych liter, ale jest bardziej agresywne, ponieważ ma na celu usunięcie wszystkich rozróżnień wielkości liter w ciągu. [...]
Nie używaj tylko lower
. Jeśli casefold
nie jest dostępne, robienie .upper().lower()
pomaga (ale tylko w pewnym stopniu).
Następnie powinieneś rozważyć akcenty. Jeśli Twój renderer czcionek jest dobry, prawdopodobnie myślisz "ê" == "ê"
- ale nie:
"ê" == "ê"
#>>> False
Wynika to z tego, że akcent na to drugie ma charakter łączący.
import unicodedata
[unicodedata.name(char) for char in "ê"]
#>>> ['LATIN SMALL LETTER E WITH CIRCUMFLEX']
[unicodedata.name(char) for char in "ê"]
#>>> ['LATIN SMALL LETTER E', 'COMBINING CIRCUMFLEX ACCENT']
Najprostszym sposobem na poradzenie sobie z tym jest unicodedata.normalize
. Prawdopodobnie chcesz skorzystać z normalizacji NFKD , ale sprawdź dokumentację. Potem się robi
unicodedata.normalize("NFKD", "ê") == unicodedata.normalize("NFKD", "ê")
#>>> True
Aby zakończyć, tutaj jest to wyrażone w funkcjach:
import unicodedata
def normalize_caseless(text):
return unicodedata.normalize("NFKD", text.casefold())
def caseless_equal(left, right):
return normalize_caseless(left) == normalize_caseless(right)
Σίσυφος
iΣΊΣΥΦΟΣ
, oznacza to podejście się nie powiedzie, ponieważ te mają być taka sama sprawa insensitively.