2012-01-19 33 views
8

Tôi đang tìm cách nhanh chóng và có thể thuận tiện trong Python 3 để dịch các chuỗi với các chữ cái không phải ascii thành các từ chỉ có chữ cái ascii.Dịch các chữ cái không có trong ASCII 7 bit thành ASCII (như ń sang n và ą thành a)

Ví dụ!

żółw => zolw

móżdżek => mozdzek

Łódź => lodz

và vân vân ...

Có rất nhiều chữ cái trong bảng chữ cái quốc gia có thể được biến thành Chữ cái ASCII (như ń đến n). Tôi có thể làm điều đó bằng tay cho ngôn ngữ của tôi (Ba Lan), bằng cách chỉ định cách dịch từng chữ cái. Nhưng có cách tự động nào để làm điều đó không? Hoặc một số thư viện mà sẽ làm những gì tôi cần?

Trăn str.encode() sẽ không làm, vì "żółw".encode('ascii', 'replace') == "???w""żółw".encode('ascii', 'ignore') == "w" ...

tôi có thể làm dịch như vậy cho chữ đánh bóng nhưng tôi không muốn làm điều đó cho mọi ngôn ngữ khác:

>>> utf8_letters = ['ą','ę','ć','ź','ż','ó','ł','ń','ś'] 
>>> ascii_letters = ['a','e','c','z','z','o','l','n','s'] 
>>> trans_dict = dict(zip(utf8_letters,ascii_letters)) 
>>> turtle = "żółw" 
>>> out = [] 
>>> for l in turtle: 
... out.append(trans_dict[l] if l in trans_dict else l) 
>>> result = ''.join(out) 
>>> result 
'zolw' 

Đoạn mã trên làm những gì tôi muốn với các chữ cái đánh bóng, nhưng nó xấu xí: < Cách tốt nhất để làm điều này là gì?

Tất nhiên bản dịch như vậy sẽ thay đổi ý nghĩa của một số từ, nhưng điều đó ok.

+1

Hãy nhớ rằng trong một số ngôn ngữ, những gì một số sẽ xem xét một lá thư có dấu được coi là một chữ cái khác biệt trong ngôn ngữ đó. Ví dụ, chữ 'å' trong tiếng Thụy Điển thường được coi là một chữ cái riêng biệt từ 'a', và không chỉ đơn giản là chữ 'a' với một chiếc nhẫn ở trên nó. – dreamlax

+0

Tôi biết điều đó ... Vấn đề là khi tôi viết bằng bút đánh bóng ở đâu đó, nơi các chữ cái quốc gia của tôi không được hỗ trợ, tôi sử dụng "bản dịch" này mà tôi đã viết. Tôi đoán mọi người từ các nước khác có cách viết riêng trong môi trường như vậy. Tôi muốn biết làm thế nào biến đổi như vậy có thể được thực hiện. – Maciek

+0

@John Saunders, cảm ơn bạn đã trả lời hoàn toàn không hợp lệ. –

Trả lời

5

Mô-đun unicodedata có thể được sử dụng cho việc này. Có chức năng thao tác với các tên ký tự Unicode: namelookup.

Bây giờ, hãy xem chúng gần hơn.

name('Ż') == 'LATIN CAPITAL LETTER Z WITH DOT ABOVE' 
name('ł') == 'LATIN SMALL LETTER L WITH STROKE' 
lookup('LATIN CAPITAL LETTER Z') == 'Z' 
lookup('LATIN SMALL LETTER L') == 'l' 

Xem mẫu? Chúng ta hãy làm một chức năng mà sử dụng nó:

import unicodedata 

def normalize_char(c): 
    try: 
     cname = unicodedata.name(c) 
     cname = cname[:cname.index(' WITH')] 
     return unicodedata.lookup(cname) 
    except (ValueError, KeyError): 
     return c 

normalize_char('ę') == 'e' 
normalize_char('Ę') == 'E' 
normalize_char('ś') == 's' 

Có vẻ cho từ VỚI trong tên nhân vật, loại bỏ tất cả mọi thứ mà đi sau nó và thức ăn nó trở lại lookup chức năng.
Nếu không có 'WITH', ValueError được nâng lên và khi không có ký tự với tên như vậy, KeyError được nâng lên, do đó hàm trả về ký tự không thay đổi.

Và đây là một chức năng "dịch" một chuỗi căn cứ vào chức năng theo thời gian:

def normalize(s): 
    return ''.join(normalize_char(c) for c in s) 

normalize('Móżdżek') == 'Mozdzek' 

Vì vậy, giải pháp này rõ ràng là rất tốt, nhưng tôi sẽ để lại cho những người trước đây bên dưới.


Module unicodedata cũng có một chức năng hứa hẹn kết quả tương tự – normalize với 'NFKD' tham số (tương thích phân hủy), nhưng nó nhớ nhất ký tự.


Nếu bạn có dữ liệu ký tự, mã bạn cung cấp có thể được cải thiện.

letters={'ł':'l', 'ą':'a', 'ń':'n', 'ć':'c', 'ó':'o', 'ę':'e', 'ś':'s', 'ź':'z', 'ż':'z'} 
trans=str.maketrans(letters) 
result=text.translate(trans) 

Here là bảng tốt với dữ liệu ký tự. Đây là JavaScript nhưng có thể được sử dụng dễ dàng cho Python.


Và nếu bạn không ngại sử dụng thư viện bên ngoài, bạn có thể muốn thử Unidecode. Nó đã được thực hiện chỉ cho việc này.

+0

Unfortunatley unicodedata.normalize ('NFKD', "żółw") == 'żółw' không phải 'zolw': ( – Maciek

+0

Điều gì về phân hủy thành NFD và sau đó vứt bỏ tất cả các dấu kết hợp? –

+0

Bảng này bạn thích là tuyệt vời và điều này Thư viện Unidecode khá hứa hẹn, vì bây giờ tôi nghĩ rằng không có cách nào tốt hơn để làm điều đó – Maciek

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