2010-09-24 30 views
90

Quiero registrar en un programa de Python si una palabra está en el diccionario de inglés.¿Cómo comprobar si una palabra es una palabra en inglés con Python?

Creo que la interfaz nltk wordnet podría ser el camino a seguir, pero no tengo ni idea de cómo usarlo para una tarea tan simple.

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

is_english_word(token.lower()) 

En el futuro, puede ser que quiera comprobar si la forma singular de la palabra está en el diccionario (por ejemplo, propiedades -> propiedades -> palabra Inglés). ¿Cómo lo lograría?

Respuesta

147

Para (mucho) más poder y flexibilidad, use una biblioteca de corrección de ortografía dedicada como PyEnchant. Hay una tutorial, o simplemente podría bucear directamente en:

>>> 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 con un par de diccionarios (EN_GB, en_US, es_ES, fr_FR), pero se puede utilizar cualquiera de los OpenOffice ones si quieres más idiomas.

Parece que hay una biblioteca de pluralización llamada inflect, pero no tengo idea de si es algo bueno.

+2

Gracias, no sabía nada sobre PyEnchant y, de hecho, es mucho más útil para el tipo de controles que quiero hacer. – Barthelemy

+0

No reconoce ? No es una palabra común, pero sé como una abreviatura de , y no sé . Solo quería señalar que la solución no es única para todos y que un proyecto diferente podría requerir diferentes diccionarios o un enfoque diferente. – dmh

+0

Bueno, si quieres un diccionario diferente, ¡siempre puedes conectar uno en la parte posterior de PyEnchant! Note por cierto que incluso el OED solo lista "helo" como obsoleto ... – katrielalex

27

Usando un conjunto para almacenar la lista de palabras porque mirando hacia arriba será más rápido:

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 

responder a la segunda parte de la pregunta, los plurales ya estaría en una buena lista de palabras, pero si Quería excluir específicamente a los de la lista por algún motivo, de hecho podría escribir una función para manejarlo. Pero las reglas de pluralización en inglés son lo suficientemente complicadas como para incluir los plurales en la lista de palabras para empezar.

En cuanto a dónde encontrar las listas de palabras en inglés, encontré varias simplemente buscando en Google "lista de palabras en inglés". Aquí hay uno: http://www.sil.org/linguistics/wordlists/english/wordlist/wordsEn.txt Puede buscar inglés británico o estadounidense si quiere específicamente uno de esos dialectos.

+8

Si comete un '' english_words' set' en lugar de un 'list', entonces' is_english_word' se ejecutará mucho más rápido. – dan04

+0

En realidad, lo rehice como dict pero tienes razón, un set es aún mejor. Actualizado. – kindall

+1

También puede eliminar '.xreadlines()' y simplemente iterar sobre 'word_file'. – FogleBird

0

Para un enfoque de web semántica, puede ejecutar sparql query against WordNet in RDF format. Básicamente solo use el módulo urllib para emitir la solicitud GET y devolver los resultados en formato JSON, parse usando el módulo python 'json'. Si no es una palabra en inglés, no obtendrá ningún resultado.

Como otra idea, puede consultar Wiktionary's API.

27

Usando NLTK:

from nltk.corpus import wordnet 

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

Debe consultar this article si tiene problemas con la instalación wordnet o si quieres probar otros enfoques.

+0

Es especialmente útil para usuarios de cygwin porque la instalación de enchant es bastante problemática. – alehro

+4

No funciona para mí. 'wordnet.synsets (" would ")' returns '[]' – morgancodes

+17

WordNet no contiene todas las palabras en inglés, solo contiene un pequeño subconjunto de ellas. – justhalf

20

No funcionará bien con WordNet, porque WordNet no contiene todas las palabras en inglés. Otra posibilidad basado en NLTK sin encantamiento es de NLTK palabras 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

Aquí también se aplica la misma mención: mucho más rápido cuando se convierte a un conjunto: 'set (words.words())' –

+0

nltk no tiene palabras como "okay". https://stackoverflow.com/questions/44449284/nltk-words-corpus-does-not-contain-okay – MonsieurBeilto

4

Para una solución más rápida basada en NLTK se podía desmenuzar el conjunto de palabras para evitar una búsqueda lineal.

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 no tiene palabras como "okay". https://stackoverflow.com/questions/44449284/nltk-words-corpus-does-not-contain-okay – MonsieurBeilto

+0

@MonsieurBeilto true. Parecen haber decidido que "bien" o "bien" no son palabras regulares. – Sadik

0

Con pyEnchant.corrector 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 
Cuestiones relacionadas