Một cách giải quyết để đạt được mục tiêu mong muốn sẽ được sử dụng unidecode để thoát khỏi tất cả các dấu đầu tiên, và sau đó chỉ cần phù hợp với agains thường xuyên e
re.match(r"^e$", unidecode("é"))
Hoặc trong trường hợp đơn giản này
unidecode("é") == "e"
Một giải pháp khác không phụ thuộc vào thư viện unidecode, bảo toàn unicode và cho phép kiểm soát nhiều hơn bằng cách xóa thủ công diacri tics như sau:
Sử dụng unicodedata.normalize() để biến chuỗi đầu vào của bạn vào mẫu bình thường D (đối với phân hủy), làm cho nhân vật chắc chắn composit như é
được biến thành dạng phức dụng e\u301
(e + Kết hợp CẤP TÍNH ACCENT)
>>> input = "Héllô"
>>> input
'Héllô'
>>> normalized = unicodedata.normalize("NFKD", input)
>>> normalized
'He\u0301llo\u0302'
Sau đó, xóa tất cả các điểm mã nằm trong danh mục Mark, Nonspacing (ngắn Mn
). Đó là tất cả các nhân vật không có chiều rộng và chỉ trang trí cho nhân vật trước đó. Sử dụng unicodedata.category() để xác định danh mục.
>>> stripped = "".join(c for c in normalized if unicodedata.category(c) != "Mn")
>>> stripped
'Hello'
Kết quả có thể được sử dụng làm nguồn cho đối sánh regex, giống như trong ví dụ unidecode ở trên. Đây là toàn bộ chức năng dưới dạng hàm:
def remove_diacritics(text):
"""
Returns a string with all diacritics (aka non-spacing marks) removed.
For example "Héllô" will become "Hello".
Useful for comparing strings in an accent-insensitive fashion.
"""
normalized = unicodedata.normalize("NFKD", text)
return "".join(c for c in normalized if unicodedata.category(c) != "Mn")
Python regex có hỗ trợ * tương tự ký tự POSIX * khớp không? Điều này đơn giản như '[= e =]' - nhưng nó cũng khớp với các giá trị vốn hóa tương đương, có thể quá nhiều trong trường hợp của bạn. Điều này có thể được làm việc xung quanh bằng cách sử dụng '(?! \ U)', mặc dù điều này lần lượt cần regex của bạn để hỗ trợ chữ hoa cho tất cả các ký tự Unicode là tốt. – usr2564301