Python - Überprüfen Sie, ob Word in einer Zeichenfolge enthalten ist


177

Ich arbeite mit Python v2 und versuche herauszufinden, ob Sie erkennen können, ob sich ein Wort in einer Zeichenfolge befindet.

Ich habe einige Informationen zum Identifizieren gefunden, ob sich das Wort in der Zeichenfolge befindet - mithilfe von .find, aber es gibt eine Möglichkeit, eine IF-Anweisung auszuführen. Ich hätte gerne so etwas wie folgendes:

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

Vielen Dank für jede Hilfe.

Antworten:


349

Was ist falsch mit:

if word in mystring: 
   print 'success'

103
Nur zur Vorsicht, wenn Sie eine Zeichenfolge "Paratyphus ist schlecht" haben und wenn Sie "Typhus" in "Paratyphus ist schlecht" ausführen, erhalten Sie eine wahre.
David Nelson

3
Weiß jemand, wie man dieses Problem löst?
user2567857

4
@ user2567857, reguläre Ausdrücke - siehe Hugh Bothwells Antwort.
Mark Rajcok

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

2
Wie ist das die akzeptierte Antwort? !! Es wird nur geprüft, ob eine Folge von Zeichen (kein Wort) in einer Zeichenfolge erscheint
pedram bashiri

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

Beachten Sie jedoch, dass dies einer Folge von Zeichen entspricht, nicht unbedingt einem ganzen Wort - zum Beispiel 'word' in 'swordsmith'ist es wahr. Wenn Sie nur ganze Wörter abgleichen möchten, sollten Sie reguläre Ausdrücke verwenden:

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
Gibt es eine wirklich schnelle Methode, um nach mehreren Wörtern zu suchen, beispielsweise nach mehreren tausend Wörtern, ohne eine for-Schleife erstellen zu müssen, die jedes Wort durchläuft? Ich habe eine Million Sätze und eine Million Begriffe, die ich durchsuchen muss, um zu sehen, welcher Satz welche passenden Wörter enthält. Derzeit dauert die Bearbeitung Tage, und ich möchte wissen, ob es einen schnelleren Weg gibt.
Tom

@ Tom versuchen, grep anstelle von Python Regex zu verwenden
El Ruso

p1 für Schwertschmied
Robino

Wie gehen Sie mit Ausnahmen um, z. B. wenn das Wort nicht in der Zeichenfolge gefunden wird?
FaCoffee

1
@FaCoffee: Wenn die Zeichenfolge nicht gefunden wird, gibt die Funktion None zurück (siehe letztes Beispiel oben).
Hugh Bothwell

48

Wenn Sie herausfinden möchten, ob sich ein ganzes Wort in einer durch Leerzeichen getrennten Liste von Wörtern befindet, verwenden Sie einfach:

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

Diese elegante Methode ist auch die schnellste. Im Vergleich zu den Ansätzen von Hugh Bothwell und 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: Eine kleine Variante dieser Idee für Python 3.6+, ebenso schnell:

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

3
Dies ist meine Lieblingsantwort :)
IanS

Ich stimme zu, aber die schnellste Lösung ignoriert nicht den Fall wie re.compile (... tut es.
Michael Smith

7
Dies hat mehrere Probleme: (1) Wörter am Ende (2) Wörter am Anfang (3) Wörter dazwischen wiecontains_word("says", "Simon says: Don't use this answer")
Martin Thoma

@MartinThoma - Wie bereits erwähnt, dient diese Methode speziell dazu, herauszufinden, "ob sich ein ganzes Wort in einer durch Leerzeichen getrennten Liste von Wörtern befindet". In dieser Situation funktioniert es gut für: (1) Wörter am Ende (2) Wörter am Anfang (3) Wörter dazwischen. Ihr Beispiel schlägt nur fehl, weil Ihre Wortliste einen Doppelpunkt enthält.
user200783

1
@JeffHeaton Wieder einmal ist diese Methode SPEZIELL für "Wenn Sie herausfinden möchten, ob sich ein ganzes Wort in einer durch Leerzeichen getrennten Liste von Wörtern befindet", wie der Autor klar angegeben hat.
Bitwitch

17

find gibt eine Ganzzahl zurück, die den Index darstellt, in dem das Suchelement gefunden wurde. Wenn es nicht gefunden wird, gibt es -1 zurück.

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

Sie können die Zeichenfolge in die Wörter aufteilen und die Ergebnisliste überprüfen.

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

3
Bitte benutzen Sie den Bearbeitungslink, um zu erklären, wie dieser Code funktioniert, und geben Sie nicht nur den Code an, da eine Erklärung eher zukünftigen Lesern helfen wird.
Jed Fox

1
Dies sollte die eigentliche Antwort sein, um das ganze Wort abzugleichen.
Kaushik NP

10

Diese kleine Funktion vergleicht alle Suchwörter im angegebenen Text. Wenn alle Suchwörter im Text gefunden werden, wird die Suchlänge oder auf Falseandere Weise zurückgegeben.

Unterstützt auch die Suche nach Unicode-Zeichenfolgen.

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

Verwendung:

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

8

Wenn das Abgleichen einer Zeichenfolge nicht ausreicht und Sie ganze Wörter abgleichen müssen, finden Sie hier eine einfache Funktion, mit der Sie Ihre Arbeit erledigen können. Grundsätzlich werden bei Bedarf Leerzeichen angehängt und in der Zeichenfolge danach gesucht:

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

Dies setzt voraus, dass Kommas und andere Satzzeichen bereits entfernt wurden.


Diese Lösung hat sich in meinem Fall am besten bewährt, da ich durch Token getrennte Zeichenfolgen verwende.
Avijit

4

Da Sie nach einem Wort und nicht nach einer Zeichenfolge fragen, möchte ich eine Lösung vorstellen, die nicht auf Präfixe / Suffixe reagiert und Groß- und Kleinschreibung ignoriert:

#!/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()

Wenn Ihre Wörter möglicherweise Regex-Sonderzeichen (z. B. +) enthalten, benötigen Sie diesere.escape(word)


3

Erweiterte Methode, um das genaue Wort zu überprüfen, das wir in einer langen Zeichenfolge finden müssen:

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

Die Verwendung von Regex ist eine Lösung, für diesen Fall jedoch zu kompliziert.

Sie können Text einfach in eine Wortliste aufteilen. Verwenden Sie dazu die Split- Methode ( Separator , Num ) . Es gibt eine Liste aller Wörter in der Zeichenfolge zurück, wobei das Trennzeichen als Trennzeichen verwendet wird. Wenn das Trennzeichen nicht angegeben ist, wird es auf alle Leerzeichen aufgeteilt (optional können Sie die Anzahl der Teilungen auf num beschränken ).

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

Dies funktioniert nicht für Zeichenfolgen mit Kommas usw. Zum Beispiel:

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

Wenn Sie auch alle Kommas usw. aufteilen möchten, verwenden Sie das folgende Trennzeichen :

# 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
Dies ist eine gute Lösung, ähnlich wie bei @Corvax, mit dem Vorteil, dass gemeinsame Zeichen zum Teilen hinzugefügt werden, sodass in einer Zeichenfolge wie "First: there .." das Wort "First" gefunden werden kann. Beachten Sie, dass @tstempko ":" nicht in den zusätzlichen Zeichen enthält. Ich würde :). Wenn bei der Suche die Groß- und Kleinschreibung nicht berücksichtigt wird, sollten Sie vor dem Teilen .lower () sowohl für das Wort als auch für die Zeichenfolge verwenden. mystring.lower().split()und word.lower() ich denke, das ist auch schneller als das Regex-Beispiel.
Beauk

0

Sie können einfach ein Leerzeichen vor und nach "Wort" hinzufügen.

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

Auf diese Weise wird nach dem Leerzeichen vor und nach "Wort" gesucht.

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

2
Aber was ist, wenn das Wort am Anfang oder am Ende des Satzes steht (kein Leerzeichen)
MikeL
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.