Regex для определения имен собственных в списке - PullRequest
1 голос
/ 20 марта 2019

У меня есть программа, которая отображает частотный список слов в тексте (токенизированный текст), но я хочу первое: найти правильные существительные текста и добавить их в другой список (Cap_nouns) второе: добавить существительные, которых нет в словаре, в другой список (ошибки),

Позже я хочу создать список частот для найденных ошибок и другой список частот для найденных имен существительных.

Моя идея определить правильные существительные состояла в том, чтобы найти элементы, начинающиеся с заглавной буквы, и добавить их в этот список, но, похоже, мое регулярное выражение для этой задачи не работает.

Может ли кто-нибудь помочь мне с этим? Мой код ниже.

from collections import defaultdict
import re
import nltk
from nltk.tokenize import word_tokenize



with open('fr-text.txt') as f:
    freq = word_tokenize(f.read())

with open ('Fr-dictionary_Upper_Low.txt') as fr:
    dic = word_tokenize(fr.read())


#regular expression to detect words with apostrophes and separated by hyphens    
pat=re.compile(r".,:;?!-'%|\b(\w'|w’)+\b|\w+(?:-\w+)+|\d+") 
reg= list(filter(pat.match, freq))
#regular expression for words that start with a capital letter
patt=re.compile(r"\b^A-Z\b")  
c_n= list(filter(patt.match, freq))

d=defaultdict(int)

#Empty list to append the items not found in the dictionary
errors=[ ]
Cnouns=[ ] #Empty list to append the items starting with a capital letter


for w in freq:
    d[w]+=1
    if w in reg:
        continue
    elif w in c_n:
        Cnouns.append(w)
    elif w not in dic:
        errors.append(w)



for w in sorted(d, key=d.get):
    print(w, d[w])


print(errors)
print(Cnouns)

Если с моим кодом что-то не так, дайте мне знать, пожалуйста.

1 Ответ

1 голос
/ 20 марта 2019

Что касается части регулярных выражений, ваши паттерны "немного отклонены". Чаще всего вы пропускаете понятие класса символов , [abc], как шаблоны, которые соответствуют одному символу из набора, определенного в классе.

Регулярное выражение для обнаружения слов с апострофами и через дефис:

pat=re.compile(r"(?:\w+['’])?\w+(?:-(?:\w+['’])?\w+)*") 

См. Демоверсию regex . Однако он также будет соответствовать обычным числам или простым словам. Чтобы избежать их соответствия, вы можете использовать

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

См. это демо регулярных выражений .

Детали

  • (?:\w+['’])? - необязательная группа без захвата, соответствующая 1 или 0 вхождениям из 1+ слов с последующими либо ', либо
  • \w+ - 1 или более символов слова
  • (?:-(?:\w+['’])?\w+)* - 0 или более повторений
    • -(?:\w+['’])? - необязательная группа без захвата, соответствующая 1 или 0 вхождениям из 1+ слов с последующими либо ', либо
    • \w+ - 1 или более слов с символами

Далее reg = list(filter(pat.match, freq)) может не выполнять то, что вам нужно, поскольку re.match соответствует только началу строки . Скорее всего, вы хотите использовать re.match:

reg = list(filter(pat.search, freq))
                      ^^^^^^

Регулярное выражение для слов, начинающихся с заглавной буквы, может быть написано как

patt=re.compile(r"\b[A-Z][a-z]*\b")  
c_n= list(filter(patt.search, freq))

См. это демо регулярных выражений

\b соответствует границе слова, [A-Z] соответствует любой прописной букве ASCII, часть [a-z]* соответствует 0 или более строчным буквам ASCII, а \b обеспечивает наличие границы слова после них.

...