Python: controlla se Word è in una stringa


178

Sto lavorando con Python v2 e sto cercando di scoprire se riesci a capire se una parola è contenuta in una stringa.

Ho trovato alcune informazioni sull'identificazione se la parola è nella stringa - usando .find, ma c'è un modo per fare un'istruzione IF. Vorrei avere qualcosa di simile al seguente:

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

Grazie per qualsiasi aiuto.

Risposte:


351

Cosa c'è di sbagliato in:

if word in mystring: 
   print 'success'

103
solo come avvertimento, se hai una stringa "paratifo è male" e fai un "tifo" se in "paratifo è cattivo" otterrai un vero.
David Nelson,

3
Qualcuno sa come superare questo problema?
user2567857

4
@ user2567857, espressioni regolari - vedi la risposta di Hugh Bothwell.
Mark Rajcok,

4
if (word1 in mystring e word2 in mystring)
louie mcconnell

2
Come è questa la risposta accettata? !! Controlla solo se una sequenza di caratteri (non una parola) appare in una stringa
pedram bashiri

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

ma tieni presente che questo corrisponde a una sequenza di caratteri, non necessariamente a una parola intera - ad esempio, 'word' in 'swordsmith'è Vero. Se vuoi solo abbinare parole intere, dovresti usare espressioni regolari:

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
Esiste un metodo veramente veloce per cercare più parole, ad esempio un insieme di diverse migliaia di parole, senza dover costruire un ciclo for che attraversi ciascuna parola? Ho un milione di frasi e un milione di termini da cercare per vedere quale frase ha quali parole corrispondenti. Al momento mi ci vogliono giorni per l'elaborazione, e voglio sapere se esiste un modo più veloce.
Tom,

@Tom prova a usare grep invece di python regex
El Ruso

p1 per spadaccino
Robino

Come gestite le eccezioni, ad esempio quando la parola non viene trovata nella stringa?
FaCoffee

1
@FaCoffee: se la stringa non viene trovata, la funzione restituisce None (vedi l'ultimo esempio sopra).
Hugh Bothwell,

48

Se vuoi scoprire se un'intera parola è in un elenco di parole separato da spazi, usa semplicemente:

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

Questo metodo elegante è anche il più veloce. Rispetto agli approcci di 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

Modifica: una leggera variante di questa idea per Python 3.6+, altrettanto veloce:

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

3
Questa è la mia risposta preferita :)
IanS

Sono d'accordo, ma la soluzione più rapida non ignora il caso come re.compile (... sì.
Michael Smith,

7
Ciò ha diversi problemi: (1) Parole alla fine (2) Parole all'inizio (3) parole tra unacontains_word("says", "Simon says: Don't use this answer")
altra

@MartinThoma - Come detto, questo metodo è specifico per scoprire "se un'intera parola è in un elenco di parole separato da spazi". In quella situazione, funziona bene per: (1) Parole alla fine (2) Parole all'inizio (3) parole in mezzo. L'esempio ha esito negativo solo perché l'elenco di parole include due punti.
user200783

1
@JeffHeaton Ancora una volta, questo metodo è SPECIFICAMENTE PER "Se vuoi scoprire se un'intera parola è in un elenco di parole separato da spazi", come chiaramente affermato dall'autore.
Bitwitch

17

find restituisce un numero intero che rappresenta l'indice del punto in cui è stato trovato l'elemento di ricerca. Se non viene trovato, restituisce -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

È possibile dividere la stringa in parole e controllare l'elenco dei risultati.

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

3
Utilizza il link di modifica per spiegare come funziona questo codice e non limitarti a fornire il codice, poiché è più probabile che una spiegazione aiuti i lettori futuri.
Jed Fox,

1
Questa dovrebbe essere la risposta effettiva per abbinare l'intera parola.
Kaushik NP,

10

Questa piccola funzione confronta tutte le parole di ricerca in un determinato testo. Se tutte le parole di ricerca vengono trovate nel testo, restituisce la lunghezza della ricerca o in Falsealtro modo.

Supporta anche la ricerca di stringhe 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

utilizzo:

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

8

Se abbinare una sequenza di caratteri non è sufficiente ed è necessario abbinare parole intere, ecco una semplice funzione che fa il lavoro. In pratica aggiunge spazi dove necessario e cerca quello nella stringa:

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

Ciò presuppone che le virgole e altre punteggiatura siano già state eliminate.


Questa soluzione ha funzionato meglio per il mio caso poiché sto usando stringhe separate di spazio tokenizzate.
Avijit,

4

Mentre stai chiedendo una parola e non una stringa, vorrei presentare una soluzione che non è sensibile ai prefissi / suffissi e ignora il caso:

#!/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 le tue parole potrebbero contenere caratteri speciali regex (come +), allora hai bisognore.escape(word)


3

Modo avanzato per controllare la parola esatta, che dobbiamo trovare in una lunga stringa:

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

L'uso di regex è una soluzione, ma è troppo complicato per quel caso.

Puoi semplicemente dividere il testo in un elenco di parole. Usa il metodo split ( separator , num ) per questo. Restituisce un elenco di tutte le parole nella stringa, usando il separatore come separatore. Se il separatore non è specificato, si divide su tutti gli spazi bianchi (facoltativamente è possibile limitare il numero di divisioni a num ).

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

Questo non funzionerà per la stringa con virgole ecc. Ad esempio:

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

Se vuoi anche dividere su tutte le virgole ecc. Usa un argomento separatore come questo:

# 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
Questa è una buona soluzione, simile a @Corvax, con il vantaggio di aggiungere caratteri comuni su cui dividere in modo che in una stringa come "First: there ..", sia stata trovata la parola "First". Nota che @tstempko non include ":" nei caratteri aggiuntivi. Vorrei :). Inoltre, se la ricerca non fa distinzione tra maiuscole e minuscole, considera l'utilizzo di .lower () sia sulla parola che sulla stringa prima della divisione. mystring.lower().split()e word.lower() penso che questo sia anche più veloce dell'esempio regex.
beauk,

0

Potresti semplicemente aggiungere uno spazio prima e dopo "parola".

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

In questo modo cerca lo spazio prima e dopo "parola".

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

2
Ma cosa succede se la parola è all'inizio o alla fine della frase (nessuno spazio)
MikeL
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.