Порівняння рядків у нечутливому випадку видається тривіальним, але це не так. Я буду використовувати Python 3, оскільки Python 2 тут недостатньо розвинений.
Перше, що слід зауважити, - це те, що конверсії для видалення випадків у Unicode не є тривіальними. Є текст, для якого text.lower() != text.upper().lower()
такі "ß"
:
"ß".lower()
#>>> 'ß'
"ß".upper().lower()
#>>> 'ss'
Але скажімо, ви хотіли безвідмовно порівнювати "BUSSE"
і "Buße"
. Чорт забирай, напевно, ти теж хочеш порівняти "BUSSE"
і "BUẞE"
дорівнювати - це новіша форма капіталу. Рекомендований спосіб casefold
:
вул. casefold ()
Повернути копію рядка зі складеною регістром копії. Рядки, складені в корпусі, можуть використовуватися для беззмістового зіставлення.
Складання корпусів подібне до нижнього корпусу, але агресивніше, оскільки воно призначене для видалення всіх відмінків у рядку. [...]
Не просто використовувати lower
. Якщо casefold
недоступний, .upper().lower()
допомагає (але лише дещо).
Тоді слід розглянути акценти. Якщо рендерінг вашого шрифту хороший, ви, напевно, думаєте "ê" == "ê"
- але це не так:
"ê" == "ê"
#>>> False
Це тому, що наголос на останньому є поєднувальним характером.
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']
Найпростіший спосіб впоратися з цим unicodedata.normalize
. Можливо, ви хочете використовувати нормалізацію NFKD , але сміливо перегляньте документацію. Тоді так і роблять
unicodedata.normalize("NFKD", "ê") == unicodedata.normalize("NFKD", "ê")
#>>> True
Для завершення тут це виражається у функціях:
import unicodedata
def normalize_caseless(text):
return unicodedata.normalize("NFKD", text.casefold())
def caseless_equal(left, right):
return normalize_caseless(left) == normalize_caseless(right)
Σίσυφος
іΣΊΣΥΦΟΣ
, то ваш підхід провалюється, тому що вони повинні бути одним і тим же випадком безчутливим.