2015-12-30 2 views
2

Я хочу создать простой скрипт 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? Что-то не так с моим кодом?

ответ

3

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

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

Если вы хотите понять причины этого «странного» поведения, вы должны знать больше о Unicode. Короче говоря, есть много писем, которые похожи, но имеют разные порядковые номера. Более того, одно и то же письмо иногда может быть представлено в нескольких формах. Таким образом, comparing unicode characters - not a trivial task.

Итак, если мне было разрешено использовать 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 
+0

Необходимо, конечно, импортировать 'unicodedata'. –

+0

Спасибо, что решил проблему. – 0x01Brain

1

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

+0

Я думаю, что вы правы, но как я могу конвертировать Unicode изолированную форму в обычный юникод? – 0x01Brain

+0

@ 0x01Brain Я бы не назвал это другой «формой»; это просто еще один персонаж. Я бы просто поместил две записи в словарь. Кстати, если мой ответ помог вам, не стесняйтесь проголосовать. – KSFT

+0

, так почему они имеют разные значения hex? – 0x01Brain

Смежные вопросы