Python - Verifique se o Word está em uma string

177

Estou trabalhando com Python v2 e estou tentando descobrir se você pode dizer se uma palavra está em uma string.

Encontrei algumas informações sobre como identificar se a palavra está na string - usando .find, mas existe uma maneira de fazer uma declaração SE. Eu gostaria de ter algo como o seguinte:

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

Obrigado por qualquer ajuda.

The Woo
fonte

Respostas:

349

O que há de errado com:

if word in mystring: 
   print 'success'
fabrizioM
fonte
103
apenas como cautela, se você tiver uma string "paratifoide ruim" e você fizer um if "tifóide" em "paratifóide ruim", será verdadeira.
19612 David Nelson
3
Alguém sabe como superar esse problema?
user2567857
4
@ user2567857, expressões regulares - veja a resposta de Hugh Bothwell.
Mark Rajcok
4
if (word1 em mystring e word2 em mystring)
Louie mcconnell
2
Como é essa a resposta aceita? !! Ele apenas verifica se uma sequência de caracteres (nem uma palavra) aparecer em uma seqüência
pedram Bashiri
168
if 'seek' in 'those who seek shall find':
    print('Success!')

mas lembre-se de que isso corresponde a uma sequência de caracteres, não necessariamente a uma palavra inteira - por exemplo, 'word' in 'swordsmith'é True. Se você deseja apenas combinar palavras inteiras, use expressões 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
Hugh Bothwell
fonte
3
Existe um método realmente rápido de procurar várias palavras, digamos um conjunto de vários milhares de palavras, sem ter que construir um loop for passando por cada palavra? Eu tenho um milhão de frases e um milhão de termos para pesquisar e ver qual frase possui quais palavras correspondentes. Atualmente, estou demorando dias para processar e quero saber se existe uma maneira mais rápida.
27416 Tom
@ Tom tentar usar grep em vez de regex python
El Ruso
p1 para ferreiro de
espada
Como você lida com exceções, por exemplo, quando a palavra não é encontrada na string?
FaCoffee #
1
@FaCoffee: se a string não for encontrada, a função retornará None (veja o último exemplo acima).
Hugh Bothwell
48

Se você deseja descobrir se uma palavra inteira está em uma lista de palavras separada por espaço, basta usar:

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 método elegante também é o mais rápido. Comparado às abordagens de Hugh Bothwell e 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

Edit: Uma ligeira variante dessa idéia para Python 3.6+, igualmente rápida:

def contains_word(s, w):
    return f' {w} ' in f' {s} '
user200783
fonte
3
Esta é a minha resposta favorita :)
IANS
Concordo, mas a solução mais rápida não ignora casos como re.compile (... faz.
Michael Smith
7
Isso tem vários problemas: (1) Palavras no final (2) Palavras no início (3) palavras no meio comocontains_word("says", "Simon says: Don't use this answer")
Martin Thoma 9/17
@ MartinThoma - Como declarado, esse método é especificamente para descobrir "se uma palavra inteira está em uma lista de palavras separadas por espaço". Nessa situação, funciona bem para: (1) Palavras no final (2) Palavras no começo (3) palavras no meio. Seu exemplo falha apenas porque sua lista de palavras inclui dois pontos.
user200783
1
@JeffHeaton Mais uma vez, esse método é ESPECIFICAMENTE para "Se você deseja descobrir se uma palavra inteira está em uma lista de palavras separadas por espaços", como o autor afirmou claramente.
bitwitch 17/02
17

find retorna um número inteiro que representa o índice de onde o item de pesquisa foi encontrado. Se não for encontrado, ele retornará -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.'
Matt Howell
fonte
13

Você pode dividir a seqüência de caracteres com as palavras e verificar a lista de resultados.

if word in string.split():
    print 'success'
Corvax
fonte
3
Use o link editar para explicar como esse código funciona e não apenas forneça o código, pois é mais provável que uma explicação ajude futuros leitores.
Jed Fox
1
Essa deve ser a resposta real para corresponder a palavra inteira.
Kaushik NP
10

Esta pequena função compara todas as palavras de pesquisa em um determinado texto. Se todas as palavras de pesquisa forem encontradas no texto, retornará a duração da pesquisa ouFalse outra forma.

Também suporta pesquisa de string 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')
Guray Celik
fonte
8

Se a correspondência de uma sequência de caracteres não for suficiente e você precisar corresponder palavras inteiras, aqui está uma função simples que realiza o trabalho. Basicamente, acrescenta espaços onde necessário e procura por isso na string:

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

Isso pressupõe que vírgulas e outras pontuações já foram removidas.

daSong
fonte
Essa solução funcionou melhor para o meu caso, pois estou usando seqüências separadas por espaço tokenizado.
Avijit
4

Como você está solicitando uma palavra e não uma string, gostaria de apresentar uma solução que não seja sensível a prefixos / sufixos e ignore maiúsculas e 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()

Se suas palavras podem conter caracteres especiais regex (como + ), será necessáriore.escape(word)

Martin Thoma
fonte
3

Maneira avançada de verificar a palavra exata que precisamos encontrar em uma sequência longa:

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"
Rameez
fonte
3

Usar regex é uma solução, mas é muito complicado para esse caso.

Você pode simplesmente dividir o texto em uma lista de palavras. Use o método split ( separator , num ) para isso. Retorna uma lista de todas as palavras da string, usando o separador como separador. Se o separador não for especificado, ele será dividido em todos os espaços em branco (opcionalmente, você pode limitar o número de divisões para num ).

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

Isso não funcionará para string com vírgulas etc. Por exemplo:

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

Se você também deseja dividir todas as vírgulas, etc., use o 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'
tstempko
fonte
1
Esta é uma boa solução, e semelhante ao @Corvax, com o benefício de adicionar caracteres comuns para dividir, para que em uma sequência como "Primeiro: lá ...", a palavra "Primeiro" possa ser encontrada. Observe que @tstempko não está incluindo ":" nos caracteres adicionais. Eu gostaria :). Além disso, se a pesquisa não diferencia maiúsculas de minúsculas, considere usar .lower () na palavra e na sequência antes da divisão. mystring.lower().split()e word.lower() acho que isso também é mais rápido que o exemplo do regex.
beauk
0

Você pode adicionar um espaço antes e depois da "palavra".

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

Desta forma, procura o espaço antes e depois da "palavra".

>>> Type your word: Swordsmith
>>> Nope
>>> Type your word:  word 
>>> Yes
PyGuy
fonte
2
Mas e se a palavra estiver no início ou no final da frase (sem espaço) #
MikeL