2010-09-24 37 views
90

Voglio verificare in un programma Python se una parola è nel dizionario inglese.Come verificare se una parola è una parola inglese con Python?

Credo che l'interfaccia wordnet nltk potrebbe essere la strada da percorrere, ma non ho idea di come utilizzarla per un compito così semplice.

def is_english_word(word): 
    pass # how to I implement is_english_word? 

is_english_word(token.lower()) 

In futuro, mi potrebbe voler verificare se la forma singolare di una parola è nel dizionario (ad esempio, le proprietà -> Proprietà -> inglese parola). Come potrei ottenere quello?

risposta

147

Per (molto) più potenza e flessibilità, utilizzare una libreria di controllo ortografico dedicata come PyEnchant. C'è un tutorial, o si può solo tuffarsi direttamente in:

>>> import enchant 
>>> d = enchant.Dict("en_US") 
>>> d.check("Hello") 
True 
>>> d.check("Helo") 
False 
>>> d.suggest("Helo") 
['He lo', 'He-lo', 'Hello', 'Helot', 'Help', 'Halo', 'Hell', 'Held', 'Helm', 'Hero', "He'll"] 
>>> 

PyEnchant viene fornito con un paio di dizionari (it_IT, en_US, de_DE, fr_FR), ma può utilizzare una qualsiasi delle OpenOffice ones se volete più lingue.

Sembra esserci una libreria di pluralizzazione denominata inflect, ma non ho idea se sia un bene.

+2

Grazie, non sapevo di PyEnchant ed è davvero molto più utile per il tipo di controllo che voglio fare. – Barthelemy

+0

Non riconosce ? Non una parola comune, ma so come abbreviazione di e non so . Volevo solo sottolineare che la soluzione non è idonea per tutti e che un progetto diverso potrebbe richiedere dizionari diversi o un approccio completamente diverso. – dmh

+0

Bene, se vuoi un dizionario diverso puoi sempre collegarne uno nella parte posteriore di PyEnchant! Nota BTW che anche l'OED elenca solo "helo" come obsoleto ... – katrielalex

27

Utilizzando un set per memorizzare l'elenco parola perché cercando prodotti sarà più veloce:

with open("english_words.txt") as word_file: 
    english_words = set(word.strip().lower() for word in word_file) 

def is_english_word(word): 
    return word.lower() in english_words 

print is_english_word("ham") # should be true if you have a good english_words.txt 

Per rispondere alla seconda parte della domanda, i plurali sarebbe già in una buona lista di parole, ma se si volevo escludere specificatamente quelli dalla lista per qualche ragione, potresti infatti scrivere una funzione per gestirli. Ma le regole di pluralizzazione inglese sono abbastanza complicate che dovrei semplicemente includere i plurali nella lista delle parole per cominciare.

Per quanto riguarda dove trovare elenchi di parole in inglese, ho trovato diversi solo da Google "elenco di parole in inglese". Eccone uno: http://www.sil.org/linguistics/wordlists/english/wordlist/wordsEn.txt Puoi Google per inglese britannico o americano se vuoi specificamente uno di quei dialetti.

+8

Se si effettua 'english_words' un' set' invece di un 'list', quindi' is_english_word' verrà eseguito molto più veloce. – dan04

+0

In realtà l'ho appena rifatto come scritto ma hai ragione, un set è ancora migliore. Aggiornato. – kindall

+1

Puoi anche eliminare '.xreadlines()' e solo scorrere su 'word_file'. – FogleBird

0

Per un approccio web semantico, è possibile eseguire un sparql query against WordNet in RDF format. In pratica basta usare il modulo urllib per emettere la richiesta GET e restituire i risultati in formato JSON, analizzare usando il modulo python 'json'. Se non è inglese, non otterrai risultati.

Come altra idea, è possibile richiedere Wiktionary's API.

27

Utilizzando NLTK:

from nltk.corpus import wordnet 

if not wordnet.synsets(word_to_test): 
    #Not an English Word 
else: 
    #English Word 

Si dovrebbe fare riferimento a this article se si hanno problemi durante l'installazione wordnet o volete provare altri approcci.

+0

È particolarmente utile per gli utenti di cygwin perché l'installazione di enchant è piuttosto problematica. – alehro

+4

Non funziona per me. 'wordnet.synsets (" would ")' restituisce '[]' – morgancodes

+17

WordNet non contiene ogni parola in inglese, contiene solo un piccolo sottoinsieme di esso. – justhalf

20

Non funzionerà bene con WordNet, perché WordNet non contiene tutte le parole inglesi. Un'altra possibilità sulla base di NLTK senza incantare è di NLTK parole corpus

>>> from nltk.corpus import words 
>>> "would" in words.words() 
True 
>>> "could" in words.words() 
True 
>>> "should" in words.words() 
True 
>>> "I" in words.words() 
True 
>>> "you" in words.words() 
True 
+0

La stessa menzione vale anche qui: molto più veloce quando convertito in un set: 'set (words.words())' –

+0

nltk non ha parole come "okay". https://stackoverflow.com/questions/44449284/nltk-words-corpus-does-not-contain-okay – MonsieurBeilto

4

Per una soluzione NLTK basata più veloce si potrebbe hash l'insieme di parole per evitare una ricerca lineare.

from nltk.corpus import words as nltk_words 
def is_english_word(word): 
    # creation of this dictionary would be done outside of 
    #  the function because you only need to do it once. 
    dictionary = dict.fromkeys(nltk_words.words(), None) 
    try: 
     x = dictionary[word] 
     return True 
    except KeyError: 
     return False 
+0

nltk non ha parole come "okay". https://stackoverflow.com/questions/44449284/nltk-words-corpus-does-not-contain-okay – MonsieurBeilto

+0

@MonsieurBeilto true. Sembra che abbiano deciso che "ok" o "ok" non sono parole regolari. – Sadik

0

Con pyEnchant.checker SpellChecker:

from enchant.checker import SpellChecker 

def is_in_english(quote): 
    d = SpellChecker("en_US") 
    d.set_text(quote) 
    errors = [err.word for err in d] 
    return False if ((len(errors) > 4) or len(quote.split()) < 3) else True 

print(is_in_english('“办理美国加州州立大学圣贝纳迪诺分校高仿成绩单Q/V2166384296加州州立大学圣贝纳迪诺分校学历学位认证')) 
print(is_in_english('“Two things are infinite: the universe and human stupidity; and I\'m not sure about the universe.”')) 

> False 
> True 
Problemi correlati