удалить из текста только неизвестные слова, но оставить знаки препинания и цифры - PullRequest
0 голосов
/ 13 марта 2019

У меня есть текст на французском языке, содержащий слова, разделенные пробелом (например, répu blique *). Я хочу удалить эти разделенные слова из текста и добавить их в список, сохраняя пунктуацию и цифры в тексте. Мой код работает для добавления слов, которые разделены, но он не работает, чтобы сохранить цифры в тексте.

import nltk
from nltk.tokenize import word_tokenize

import re

with open ('french_text.txt') as tx: 
#opening text containing the separated words
    #stores the text with the separated words
    text = word_tokenize(tx.read().lower()) 


with open ('Fr-dictionary.txt') as fr:  #opens the dictionary
    dic = word_tokenize(fr.read().lower()) #stores the first dictionary

pat=re.compile(r'[.?\-",:]+|\d+')

out_file=open("newtext.txt","w") #defining name of output file
valid_words=[ ] #empty list to append the words checked by the dictionary 
invalid_words=[ ] #empty list to append the errors found

for word in text:
    reg=pat.findall(word)
    if reg is True:
        valid_words.append(word)
    elif word in dic:
        valid_words.append(word)#appending to a list the words checked 
    else:
        invalid_words.append(word) #appending the invalid_words



a=' '.join(valid_words) #converting list into a string

print(a) #print converted list
print(invalid_words) #print errors found

out_file.write(a) #writing the output to a file

out_file.close()

так, с этим кодом мой список ошибок идет с цифрами.

['ments', 'prési', 'répu', 'blique', 'diri', 'geants', '»', 'grand-est', 'elysée', 'emmanuel', 'macron', 'sncf', 'pepy', 'montparnasse', '1er', '2017.', 'geoffroy', 'hasselt', 'afp', 's', 'empare', 'sncf', 'grand-est', '26', 'elysée', 'emmanuel', 'macron', 'sncf', 'saint-dié', 'epinal', '23', '2018', 'etat', 's', 'vosges', '2018']

Я думаю, что проблема с регулярным выражением. Какие-либо предложения? Спасибо !!

Ответы [ 2 ]

0 голосов
/ 14 марта 2019

Предостережение пользователя : на самом деле это сложная проблема, потому что все зависит от того, что мы определяем как слово:

  • - это l’Académie одно слово, како j’eus?
  • - это gallo-romanes одно слово, или c'est-à-dire?
  • как насчет J.-C.?
  • и xiv(e) (с надстрочным индексом,как в 14 осле)?
  • , а затем QDN или QQ1 или LOL?

Вот прямое решение , которое суммируется как:

  1. разбить текст на «слова» и «не слова» (знаки препинания, пробелы)
  2. проверить «слова» по словарю
# Adjust this to your locale
WORD = re.compile(r'\w+')

text = "foo bar, baz"

while True:
    m = WORD.search(text)
    if not m:
        if text:
            print(f"punctuation: {text!r}")
        break
    start, end = m.span()
    punctuation = text[:start]
    word = text[start:end]
    text = text[end:]
    if punctuation:
        print(f"punctuation: {punctuation!r}")
    print(f"possible word: {word!r}")

possible word: 'foo'
punctuation: ' '
possible word: 'bar'
punctuation: ', '
possible word: 'baz'

У меня возникает ощущениечто вы пытаетесь иметь дело с преднамеренно ошибочными / разбитыми словами, например, если кто-то пытается обойти правила черного списка форумов или анализ речи.

Тогда лучший подход будет выглядеть так:

  1. определить, что может быть «словом» или «не словом», используя словарь
  2. , затем разбить текст

Если исходный текст былСозданный для того, чтобы уклоняться от компьютеров, но быть читаемым людьми, лучшим вариантом будет ML / AI, скорее всего, нейронная сеть, подобная RNN, используемой для идентификации объектов на изображениях.

0 голосов
/ 14 марта 2019

Проблема в вашем операторе if, где вы проверяете reg is True. Вы не должны использовать оператор is с True, чтобы проверить, был ли результат pat.findall(word) положительным (т. Е. У вас было соответствующее слово).

Вы можете сделать это вместо:

for word in text:
    if pat.match(word):
        valid_words.append(word)
    elif word in dic:
        valid_words.append(word)#appending to a list the words checked 
    else:
        invalid_words.append(word) #appending the invalid_words
...