2013-06-13 49 views
7

Cách đơn giản nhất để loại bỏ các công cụ sửa đổi ký tự từ một chuỗi unicode bằng Python là gì?Biến đổi ký tự unicode dạng dải

Ví dụ:

Arthur nên trở thành Arthur

Tôi đã thử các tài liệu nhưng tôi không thể tìm thấy bất cứ điều gì mà thực hiện điều này.

Trả lời

6

Hãy thử điều này

import unicodedata 
a = u"STRING GOES HERE" # using an actual string would break stackoverflow's code formatting. 
u"".join(x for x in a if not unicodedata.category(x).startswith("M")) 

này sẽ loại bỏ tất cả các ký tự phân loại như nhãn hiệu, đó là những gì tôi nghĩ rằng bạn muốn. Nói chung, bạn có thể lấy danh mục của một ký tự với unicodedata.category.

+3

+1. Nhưng tốt hơn nên sử dụng '.startswith ('M')' thay vì ''M' trong' ở đây. Kể từ 6.1, không có danh mục phụ 'M' thuộc bất kỳ danh mục nào, nhưng không có quy tắc nào nói rằng không thể có trong tương lai. – abarnert

+0

@abarnert: Vì vậy, bạn đang nói nó tốt hơn để sử dụng một cái gì đó có thể phá vỡ trong tương lai? – martineau

+0

@martineau: Không, tốt hơn là nên sử dụng thứ gì đó mà _will not_ đột nhập trong tương lai. Nếu một danh mục con của danh mục 'M' được thêm vào, thì nó sẽ là để kết hợp các nhãn hiệu. Nếu một danh mục con 'M' mới của một số danh mục khác được thêm vào, nó sẽ không được dùng để kết hợp các nhãn hiệu. Vì vậy, quy tắc phù hợp để kết hợp các dấu là 'cat.startswith ('M')', không phải ''M' trong cat'. (Nó không phải là _that_ có khả năng xuất hiện, bởi vì họ chưa thêm bất kỳ tiểu thể loại mới nào dùng chung các chữ cái được sử dụng bởi các danh mục chính, và dọn sạch các chữ cái hiện có, 'LC'. Nhưng không có hại gì khi làm điều đúng, và tại ít nhất lợi ích tiềm năng.) – abarnert

5

Bạn cũng có thể sử dụng r'\p{M}' được hỗ trợ bởi regex module:

import regex 

def remove_marks(text): 
    return regex.sub(ur"\p{M}+", "", text) 

Ví dụ:

>>> print s 
A͋͠r͍̞̫̜t̼̭͞h́u̡̙̞̘rͬͣ̐ͮ 
>>> def remove_marks(text): 
...  return regex.sub(ur"\p{M}+", "", text) 
...  
... 
>>> print remove_marks(s) 
Arthur 

Tùy thuộc vào tình huống sử dụng của bạn một cách tiếp cận danh sách trắng có thể là ví dụ tốt hơn, để hạn chế đầu vào chỉ thành các ký tự ascii:

>>> s.encode('ascii', 'ignore').decode('ascii') 
u'Arthur' 

Kết quả có thể phụ thuộc vào chuẩn hóa Unicode được sử dụng trong văn bản.

+0

Điểm tốt về việc chuẩn hóa - một hoặc nhiều dấu có thể được tạo thành một trong các chữ cái, trong trường hợp này bạn sẽ mất chữ đó. Nhưng bạn có thể giải quyết điều đó bằng cách thực hiện 'unicoredata.normalize ('NFD', s) .encode ('ascii', 'ignore') giải mã ('ascii')'. (Bạn có thể muốn sử dụng 'NFKD' thay vào đó, tùy thuộc vào việc bạn có nhận được những thứ như U + 2160 ('Ⅰ') hay không, liệu bạn có muốn coi chúng là tương đương U + 0049 tương đương hay không (' I') hoặc bỏ qua chúng.) – abarnert

Các vấn đề liên quan