Как отобразить арабские буквы в фонемы в 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] строка это юникод? Что-то не так с моим кодом?

2 ответа

Решение

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

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

Если вы действительно хотите понять причины этого "странного" поведения, вам следует больше узнать о 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'(Арабская буква ALEF ISOLATED FORM), которая выглядит аналогично, но у вас нет ا (u'\u0627', Арабское письмо alef).

Другие вопросы по тегам