Python: нормализация текстового файла

У меня есть текстовый файл, который содержит несколько вариантов написания многих слов:

Например,

identification ... ID .. identity...contract.... contr.... contractor...medicine...pills..tables

Итак, я хочу иметь текстовый файл синонимов, который содержит синонимы слов, и хотел бы заменить все варианты основным словом. По сути, я хочу нормализовать входной файл.

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

identification = ID identify
contracting = contract contractor contractors contra...... 
word3 = word3_1 word3_2 word3_3 ..... word3_n
.
.
.
.
medicine = pills tables drugs...

Я хочу, чтобы конечный выходной файл выглядел так

identification ... identification .. identification...contractor.... contractor.... contractor...medicine...medicine..medicine

Как я начал программировать на питоне?

Спасибо большое за вашу помощь!!!


person Zenvega    schedule 10.09.2011    source источник


Ответы (2)


Вы можете прочитать файл синонимов и преобразовать его в словарь, table:

import re

table={}
with open('synonyms','r') as syn:
    for line in syn:
        match=re.match(r'(\w+)\s+=\s+(.+)',line)
        if match:
            primary,synonyms=match.groups()
            synonyms=[synonym.lower() for synonym in synonyms.split()]
            for synonym in synonyms:
                table[synonym]=primary.lower()

print(table)

урожаи

{'word3_1': 'word3', 'word3_3': 'word3', 'word3_2': 'word3', 'contr': 'contracting', 'contract': 'contracting', 'contractor': 'contracting', 'contra': 'contracting', 'identify': 'identification', 'contractors': 'contracting', 'word3_n': 'word3', 'ID': 'identification'}

Затем вы можете прочитать текстовый файл и заменить каждое слово его основным синонимом из table:

with open('textfile','r') as f:
    for line in f:
        print(''.join(table.get(word.lower(),word) 
                      for word in re.findall(r'(\W+|\w+)',line)))

урожаи

identification     identification    identity   contracting     contracting     contracting   medicine   medicine  medicine

  1. re.findall(r'(\w+|\W+)',line) использовался для разделения каждого line с сохранением пробелов. Если пробел не представляет интереса, вы также можете использовать более простой вариант line.split().
  2. table.get(word,word) возвращает table[word], если слово находится в table, и просто возвращает word, если word не находится в синониме table.
person unutbu    schedule 10.09.2011
comment
Разделение пробелами добавит конечные знаки препинания - например, покажите мне свой идентификатор. если разделить на пробелы, не будет давать красивую чистую строку идентификатора для преобразования в идентификацию. Верхний/нижний регистр также должен быть обработан. - person PaulMcG; 11.09.2011
comment
@Paul McGuire: Спасибо за комментарий. Я изменил \s+|\S+ на \w+|\W+, чтобы отделить знаки препинания от слов, и добавил код для обработки регистра. @Pradeep: эти изменения имеют маловероятные, но, возможно, проблемные последствия: слова со знаками препинания (например, can't) в списке синонимов больше не будут совпадать, а слова, значение которых меняется в зависимости от регистра (Polish — национальность, а polish — глагол), могут быть заменены. одним и тем же синонимом. Эти проблемы можно решить с помощью дополнительного кода, но давайте не будем этого делать, если только это не повлияет на вашу ситуацию. - person unutbu; 11.09.2011

Просто мысль: вместо списка всех вариантов слова взгляните на difflib

>>> get_close_matches('appel', ['ape', 'apple', 'peach', 'puppy'])
['apple', 'ape']
>>> import keyword
>>> get_close_matches('wheel', keyword.kwlist)
['while']
>>> get_close_matches('apple', keyword.kwlist)
[]
>>> get_close_matches('accept', keyword.kwlist)
['except']
person Fredrik Pihl    schedule 10.09.2011
comment
Спасибо .. Мне понадобится этот тип эвристики при очистке. Я намерен изучить это на несколько более продвинутой стадии приложения, над которым я работаю. - person Zenvega; 11.09.2011