Как сопоставить арабские буквы для фонем в Python?

Я хочу создать простой скрипт Python, который отобразит каждое арабское письмо на звуковые символы фонемы. У меня есть файл, в котором есть куча слов, которые скрипт будет читать, чтобы преобразовать их в фонемы, и у меня есть следующий словарь в моем коде:

Содержимое в файле .txt :

 السلام عليكم السلام عليكم و رحمة الله السلام عليكم و رحمة الله و بركاته الحمد لله كيف حالك كيف الحال 

Словарь в моем коде:

 ar_let_phon_maplist = {u'ﺍ':'A:', u'ﺏ':'B', u'ﺕ':'T', u'ﺙ':'TH', u'ﺝ':'J', u'ﺡ':'H', u'ﺥ':'KH', u'ﻩ':'H', u'ﻉ':'(ayn) '', u'ﻍ':'GH', u'ﻑ':'F', u'ﻕ':'q', u'ﺹ':u'ṣ', u'ﺽ':u'ḍ', u'ﺩ':'D', u'ﺫ':'DH', u'ﻁ':u'ṭ', u'ﻙ':'K', u'ﻡ':'M', u'ﻥ':'N', u'ﻝ':'L', u'ﻱ':'Y', u'ﺱ':'S', u'ﺵ':'SH', u'ﻅ':u'ẓ', u'ﺯ':'Z', u'ﻭ':'W', u'ﺭ':'R'} 

У меня есть вложенный цикл, где я читаю каждую строку, конвертируя каждый символ:

 with codecs.open(sys.argv[1], 'r', encoding='utf-8') as file: lines = file.readlines() line_counter = 0 for line in lines: print "Phonetics In Line " + str(line_counter) print line + " ", for word in line: for character in word: if character == '\n': print "" elif character == ' ': print " " else: print ar_let_phon_maplist[character] + " ", line_counter +=1 

И это ошибка, которую я получаю:

 Phonetics In Line 0 السلام عليكم Traceback (most recent call last): File "grapheme2phoneme.py", line 25, in <module> print ar_let_phon_maplist[character] + " ", KeyError: u'\u0627' 

И затем я проверил, является ли тип файла UTF-8 с помощью команды Linux:

 file words.txt 

Выход, который я получил:

 words.txt: UTF-8 Unicode text 

Любое решение этой проблемы, почему это не сопоставление с объектом Unicode, находящимся в словаре, так как и символ, который я использую как ключ в ar_let_phon_maplist[character] является Unicode? Что-то не так с моим кодом?

Первое, что бросается в глаза, – KeyError . Поэтому ваш словарь просто не знает о некоторых символах, встречающихся в файле. Забегая вперед, он не знает о ЛЮБОЙ из представленных персонажей, а не только о первом.

Что мы можем с этим сделать? Хорошо, мы можем просто добавить все символы из арабского сегмента таблицы Юникода в наш словарь. Просто? Да. Очистить? Нет.

Если вы хотите понять причины этого «странного» поведения, вы должны знать больше о Unicode. Короче говоря, есть много писем, которые похожи, но имеют разные порядковые номера. Более того, одно и то же письмо иногда может быть представлено в нескольких формах. Поэтому сравнение символов Unicode не является тривиальной задачей .

Итак, если мне разрешили использовать Python 3.3+, я бы решил задачу следующим образом. Сначала я нормализую ключи в словаре ar_let_phon_maplist :

 ar_let_phon_maplist = {unicodedata.normalize('NFKD', k): v for k, v in ar_let_phon_maplist.items()} 

И тогда мы будем перебирать строки в файле, слова в строке и символы в слове вроде этого:

 for index, line in enumerate(lines): print('Phonetics in line {0}, total {1} symbols'.format(index, len(line))) unknown = [] # Here will be stored symbols that we haven't found in dict words = line.split() for word in words: print(word, ': ', sep='', end='') for character in word: c = unicodedata.normalize('NFKD', character).casefold() try: print(ar_let_phon_maplist[c], sep='', end='') except KeyError: print('_', sep='', end='') if c not in unknown: unknown.append(c) print() if unknown: print('Unrecognized symbols: {0}, total {1} symbols'.format(', '.join(unknown), len(unknown))) 

Скрипт произведет нечто подобное:

 Phonetics in line 4, total 9 symbols كيف: KYF حالك: HA:LK 

Похоже, вы забыли этого символа в словаре. У вас есть ( u'\ufe8d' , ARABIC LETTER u'\ufe8d' FORM), которая выглядит аналогично, но у вас нет ا ( u'\u0627' , ARABIC LETTER ALEF).