So sánh các chuỗi trong một trường hợp không nhạy cảm có vẻ tầm thường, nhưng thực tế không phải vậy. Tôi sẽ sử dụng Python 3, vì Python 2 chưa được phát triển ở đây.
Điều đầu tiên cần lưu ý là các chuyển đổi loại bỏ trường hợp trong Unicode không phải là nhỏ. Có văn bản trong đó text.lower() != text.upper().lower()
, chẳng hạn như "ß"
:
"ß".lower()
#>>> 'ß'
"ß".upper().lower()
#>>> 'ss'
Nhưng hãy nói rằng bạn muốn vô tình so sánh "BUSSE"
và "Buße"
. Heck, có lẽ bạn cũng muốn so sánh "BUSSE"
và "BUẞE"
bằng nhau - đó là hình thức vốn mới hơn. Cách được đề xuất là sử dụng casefold
:
str. casefold ()
Trả về một bản sao của chuỗi. Các chuỗi Casefolded có thể được sử dụng để kết hợp ngẫu nhiên.
Casefold tương tự như hạ cấp nhưng tích cực hơn vì nó nhằm loại bỏ tất cả các phân biệt trường hợp trong một chuỗi. [...]
Đừng chỉ sử dụng lower
. Nếu casefold
không có sẵn, làm .upper().lower()
giúp (nhưng chỉ phần nào).
Sau đó, bạn nên xem xét các dấu. Nếu trình kết xuất phông chữ của bạn tốt, có thể bạn nghĩ "ê" == "ê"
- nhưng nó không:
"ê" == "ê"
#>>> False
Điều này là do các điểm nhấn ở sau là một nhân vật kết hợp.
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']
Cách đơn giản nhất để đối phó với điều này là unicodedata.normalize
. Bạn có thể muốn sử dụng chuẩn hóa NFKD , nhưng vui lòng kiểm tra tài liệu. Sau đó, một
unicodedata.normalize("NFKD", "ê") == unicodedata.normalize("NFKD", "ê")
#>>> True
Để kết thúc, ở đây điều này được thể hiện trong các chức năng:
import unicodedata
def normalize_caseless(text):
return unicodedata.normalize("NFKD", text.casefold())
def caseless_equal(left, right):
return normalize_caseless(left) == normalize_caseless(right)
Σίσυφος
vàΣΊΣΥΦΟΣ
, thì cách tiếp cận của bạn không thành công, bởi vì những chuỗi đó được cho là cùng một trường hợp không nhạy cảm.