Python: compruebe si Word está en una cadena


177

Estoy trabajando con Python v2, y estoy tratando de averiguar si puedes decir si una palabra está en una cadena.

He encontrado información sobre cómo identificar si la palabra está en la cadena, usando .find, pero hay una manera de hacer una declaración IF. Me gustaría tener algo como lo siguiente:

if string.find(word):
    print 'success'

Gracias por cualquier ayuda.

Respuestas:


349

Lo que está mal con:

if word in mystring: 
   print 'success'

103
solo como precaución, si tiene una cadena "paratifoide es malo" y hace un "if tifoide" en "paratifoide es malo" obtendrá un verdadero.
David Nelson

3
Alguien sabe cómo superar este problema?
user2567857

44
@ user2567857, expresiones regulares - vea la respuesta de Hugh Bothwell.
Mark Rajcok

44
if (word1 en mystring y word2 en mystring)
louie mcconnell

2
¿Cómo es esta la respuesta aceptada? Sólo comprueba si una secuencia de caracteres (no una palabra) aparecen en una cadena
Pedram Bashiri

168
if 'seek' in 'those who seek shall find':
    print('Success!')

pero tenga en cuenta que esto coincide con una secuencia de caracteres, no necesariamente una palabra completa, por ejemplo, 'word' in 'swordsmith'es Verdadero. Si solo desea hacer coincidir palabras enteras, debe usar expresiones regulares:

import re

def findWholeWord(w):
    return re.compile(r'\b({0})\b'.format(w), flags=re.IGNORECASE).search

findWholeWord('seek')('those who seek shall find')    # -> <match object>
findWholeWord('word')('swordsmith')                   # -> None

3
¿Existe un método realmente rápido para buscar varias palabras, digamos un conjunto de varios miles de palabras, sin tener que construir un bucle for que pase por cada palabra? Tengo un millón de oraciones y un millón de términos para buscar y ver qué oración tiene qué palabras coincidentes. Actualmente, me está tomando días procesarlo, y quiero saber si hay una forma más rápida.
Tom

@ Tom intenta usar grep en lugar de python regex
El Ruso

p1 para espadachín
Robino

¿Cómo maneja las excepciones, por ejemplo, cuando la palabra no se encuentra en la cadena?
FaCoffee

1
@FaCoffee: si no se encuentra la cadena, la función devuelve None (consulte el último ejemplo anterior).
Hugh Bothwell

48

Si desea averiguar si una palabra completa está en una lista de palabras separadas por espacios, simplemente use:

def contains_word(s, w):
    return (' ' + w + ' ') in (' ' + s + ' ')

contains_word('the quick brown fox', 'brown')  # True
contains_word('the quick brown fox', 'row')    # False

Este elegante método es también el más rápido. En comparación con los enfoques de Hugh Bothwell y daSong:

>python -m timeit -s "def contains_word(s, w): return (' ' + w + ' ') in (' ' + s + ' ')" "contains_word('the quick brown fox', 'brown')"
1000000 loops, best of 3: 0.351 usec per loop

>python -m timeit -s "import re" -s "def contains_word(s, w): return re.compile(r'\b({0})\b'.format(w), flags=re.IGNORECASE).search(s)" "contains_word('the quick brown fox', 'brown')"
100000 loops, best of 3: 2.38 usec per loop

>python -m timeit -s "def contains_word(s, w): return s.startswith(w + ' ') or s.endswith(' ' + w) or s.find(' ' + w + ' ') != -1" "contains_word('the quick brown fox', 'brown')"
1000000 loops, best of 3: 1.13 usec per loop

Editar: Una ligera variante de esta idea para Python 3.6+, igualmente rápido:

def contains_word(s, w):
    return f' {w} ' in f' {s} '

3
Esta es mi respuesta favorita :)
IanS

Estoy de acuerdo, pero la solución más rápida no ignora casos como re.compile (... sí.
Michael Smith

77
Esto tiene varios problemas: (1) Palabras al final (2) Palabras al principio (3) palabras intermedias comocontains_word("says", "Simon says: Don't use this answer")
Martin Thoma

@MartinThoma: como se indicó, este método es específicamente para averiguar "si una palabra completa está en una lista de palabras separadas por espacios". En esa situación, funciona bien para: (1) Palabras al final (2) Palabras al principio (3) palabras intermedias. Su ejemplo solo falla porque su lista de palabras incluye dos puntos.
user200783

1
@JeffHeaton Una vez más, este método es ESPECÍFICAMENTE para "Si desea averiguar si una palabra completa está en una lista de palabras separadas por espacios", como el autor afirmó claramente.
bitwitch

17

find devuelve un número entero que representa el índice de dónde se encontró el elemento de búsqueda. Si no se encuentra, devuelve -1.

haystack = 'asdf'

haystack.find('a') # result: 0
haystack.find('s') # result: 1
haystack.find('g') # result: -1

if haystack.find(needle) >= 0:
  print 'Needle found.'
else:
  print 'Needle not found.'

13

Puede dividir la cadena en las palabras y verificar la lista de resultados.

if word in string.split():
    print 'success'

3
Utilice el enlace de edición para explicar cómo funciona este código y no solo dé el código, ya que es más probable que una explicación ayude a los futuros lectores.
Jed Fox

1
Esta debería ser la respuesta real para hacer coincidir la palabra completa.
Kaushik NP

10

Esta pequeña función compara todas las palabras de búsqueda en un texto dado. Si todas las palabras de búsqueda se encuentran en el texto, devuelve la duración de la búsqueda, o de lo Falsecontrario.

También es compatible con la búsqueda de cadenas unicode.

def find_words(text, search):
    """Find exact words"""
    dText   = text.split()
    dSearch = search.split()

    found_word = 0

    for text_word in dText:
        for search_word in dSearch:
            if search_word == text_word:
                found_word += 1

    if found_word == len(dSearch):
        return lenSearch
    else:
        return False

uso:

find_words('çelik güray ankara', 'güray ankara')

8

Si emparejar una secuencia de caracteres no es suficiente y necesita unir palabras completas, aquí hay una función simple que hace el trabajo. Básicamente agrega espacios donde es necesario y busca eso en la cadena:

def smart_find(haystack, needle):
    if haystack.startswith(needle+" "):
        return True
    if haystack.endswith(" "+needle):
        return True
    if haystack.find(" "+needle+" ") != -1:
        return True
    return False

Esto supone que las comas y otros signos de puntuación ya se han eliminado.


Esta solución funcionó mejor para mi caso, ya que estoy usando cadenas separadas por espacios tokenizados.
Avijit

4

Como está pidiendo una palabra y no una cadena, me gustaría presentar una solución que no sea sensible a los prefijos / sufijos e ignore mayúsculas y minúsculas:

#!/usr/bin/env python

import re


def is_word_in_text(word, text):
    """
    Check if a word is in a text.

    Parameters
    ----------
    word : str
    text : str

    Returns
    -------
    bool : True if word is in text, otherwise False.

    Examples
    --------
    >>> is_word_in_text("Python", "python is awesome.")
    True

    >>> is_word_in_text("Python", "camelCase is pythonic.")
    False

    >>> is_word_in_text("Python", "At the end is Python")
    True
    """
    pattern = r'(^|[^\w]){}([^\w]|$)'.format(word)
    pattern = re.compile(pattern, re.IGNORECASE)
    matches = re.search(pattern, text)
    return bool(matches)


if __name__ == '__main__':
    import doctest
    doctest.testmod()

Si sus palabras pueden contener caracteres especiales regex (como +), entonces necesitare.escape(word)


3

Manera avanzada de verificar la palabra exacta, que necesitamos encontrar en una cadena larga:

import re
text = "This text was of edited by Rock"
#try this string also
#text = "This text was officially edited by Rock" 
for m in re.finditer(r"\bof\b", text):
    if m.group(0):
        print "Present"
    else:
        print "Absent"

3

Usar regex es una solución, pero es demasiado complicado para ese caso.

Simplemente puede dividir el texto en una lista de palabras. Utilice el método de división ( separador , num ) para eso. Devuelve una lista de todas las palabras en la cadena, usando separador como separador. Si el separador no está especificado, se divide en todos los espacios en blanco (opcionalmente, puede limitar el número de divisiones a num ).

list_of_words = mystring.split()
if word in list_of_words:
    print 'success'

Esto no funcionará para cadenas con comas, etc. Por ejemplo:

mystring = "One,two and three"
# will split into ["One,two", "and", "three"]

Si también desea dividir en todas las comas, etc., use un argumento separador como este:

# whitespace_chars = " \t\n\r\f" - space, tab, newline, return, formfeed
list_of_words = mystring.split( \t\n\r\f,.;!?'\"()")
if word in list_of_words:
    print 'success'

1
Esta es una buena solución, y similar a @Corvax, con el beneficio de agregar caracteres comunes para dividir de modo que en una cadena como "Primero: allí ...", se pueda encontrar la palabra "Primero". Tenga en cuenta que @tstempko no incluye ":" en los caracteres adicionales. Me gustaría :). Además, si la búsqueda no distingue entre mayúsculas y minúsculas, considere usar .lower () tanto en la palabra como en la cadena antes de la división. mystring.lower().split()y word.lower() creo que esto también es más rápido que el ejemplo de expresiones regulares.
beauk

0

Puede agregar un espacio antes y después de "palabra".

x = raw_input("Type your word: ")
if " word " in x:
    print "Yes"
elif " word " not in x:
    print "Nope"

De esta forma se busca el espacio antes y después de "palabra".

>>> Type your word: Swordsmith
>>> Nope
>>> Type your word:  word 
>>> Yes

2
Pero, ¿qué pasa si la palabra está al principio o al final de la oración (sin espacio)
MikeL
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.