Python - Проверьте, есть ли слово в строке


178

Я работаю с Python v2, и я пытаюсь выяснить, можете ли вы сказать, есть ли слово в строке.

Я нашел некоторую информацию об идентификации, если слово находится в строке - используя .find, но есть ли способ сделать оператор IF. Я хотел бы иметь что-то вроде следующего:

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

Спасибо за любую помощь.

Ответы:


351

Что не так с:

if word in mystring: 
   print 'success'

103
В качестве предостережения, если у вас есть строка «паратиф - это плохо», и вы делаете «если тиф» в «паратиф - это плохо», вы получите истинное значение.
Дэвид Нельсон

3
Кто-нибудь знает, как преодолеть эту проблему?
user2567857

4
@ user2567857, регулярные выражения - см. ответ Хью Ботвелла.
Марк Райкок

4
if (word1 в mystring и word2 в mystring)
Луи Макконнелл

2
Как это принятый ответ? !! Он просто проверяет, появляется ли последовательность символов (а не слово) в строке
pedram bashiri

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

но имейте в виду, что это соответствует последовательности символов, а не обязательно целому слову - например, 'word' in 'swordsmith'True. Если вы хотите сопоставлять только целые слова, вам следует использовать регулярные выражения:

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
Существует ли действительно быстрый способ поиска нескольких слов, скажем, набора из нескольких тысяч слов, без необходимости создания цикла for, проходящего через каждое слово? У меня есть миллион предложений и миллион терминов для поиска, чтобы увидеть, какое предложение имеет какие совпадающие слова. В настоящее время процесс обработки занимает у меня несколько дней, и я хочу знать, есть ли более быстрый способ.
Том

@Tom попробуйте использовать grep вместо регулярных выражений Python
El Ruso

p1 для мечей
Робиньо

Как вы обрабатываете исключения, например, когда слово не найдено в строке?
FaCoffee

1
@FaCoffee: если строка не найдена, функция возвращает None (см. Последний пример выше).
Хью Ботвелл

48

Если вы хотите узнать, находится ли все слово в списке слов, разделенных пробелами, просто используйте:

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

Этот элегантный метод также самый быстрый. По сравнению с подходами Хью Ботвелла и ДаСонга:

>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

Редактировать: Небольшой вариант этой идеи для Python 3.6+, такой же быстрый:

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

3
Это мой любимый ответ :)
IanS

Я согласен, но самое быстрое решение не игнорирует случай, как re.compile (... делает.
Майкл Смит

7
Это имеет несколько проблем: (1) Слова в конце (2) Слова в начале (3) Слова между ними, какcontains_word("says", "Simon says: Don't use this answer")
Мартин Тома

@MartinThoma - Как уже говорилось, этот метод специально предназначен для выяснения, «находится ли целое слово в списке слов, разделенных пробелами». В этой ситуации он отлично работает для: (1) слов в конце (2) слов в начале (3) слов между ними. Ваш пример терпит неудачу только потому, что ваш список слов включает двоеточие.
user200783

1
@JeffHeaton Еще раз, этот метод специально для "Если вы хотите выяснить, есть ли целое слово в списке слов, разделенных пробелами", как четко сказал автор.
bitwitch

17

find возвращает целое число, представляющее индекс, где был найден элемент поиска. Если он не найден, он возвращает -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

Вы можете разбить строку на слова и проверить список результатов.

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

3
Пожалуйста, используйте ссылку редактирования, чтобы объяснить, как работает этот код, а не просто давать код, так как объяснение с большей вероятностью поможет будущим читателям.
Джед Фокс

1
Это должен быть фактический ответ для соответствия всего слова.
Каушик Н.П.

10

Эта небольшая функция сравнивает все поисковые слова в данном тексте. Если все искомые слова найдены в тексте, возвращает длину поиска илиFalse иным образом.

Также поддерживает поиск строки 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

использование:

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

8

Если сопоставления последовательности символов недостаточно, и вам нужно сопоставить целые слова, вот простая функция, которая выполняет работу. Он в основном добавляет пробелы, где это необходимо, и ищет его в строке:

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

Это предполагает, что запятые и другие знаки препинания уже удалены.


Это решение работает лучше всего для моего случая, так как я использую строки, разделенные пробелами.
Avijit

4

Поскольку вы запрашиваете слово, а не строку, я хотел бы представить решение, которое не чувствительно к префиксам / суффиксам и игнорирует регистр:

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

Если ваши слова могут содержать специальные символы регулярного выражения (например, +), то вам нужноre.escape(word)


3

Расширенный способ проверить точное слово, которое нам нужно найти в длинной строке:

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

Использование регулярных выражений является решением, но оно слишком сложно для этого случая.

Вы можете просто разбить текст на список слов. Для этого используйте метод split ( separator , num ) . Возвращает список всех слов в строке, используя разделитель в качестве разделителя. Если разделитель не указан, он разделяется на все пустое пространство (по желанию вы можете ограничить количество разделений до num ).

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

Это не будет работать для строки с запятыми и т. Д. Например:

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

Если вы также хотите разделить все запятые и т. Д., Используйте аргумент- разделитель, например:

# 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
Это хорошее решение, похожее на @Corvax, с преимуществом добавления общих символов для разделения, чтобы в строке типа «First: there ..» можно было найти слово «First». Обратите внимание, что @tstempko не включает ":" в дополнительные символы. Я буду :). Кроме того, если при поиске не учитывается регистр, рассмотрите возможность использования .lower () как для слова, так и для строки перед разделением. mystring.lower().split()и word.lower() я думаю, что это также быстрее, чем пример регулярных выражений.
beauk

0

Вы можете просто добавить пробел до и после слова.

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

Таким образом, он ищет пространство до и после слова.

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

2
Но что, если слово находится в начале или в конце предложения (без пробела)
MikeL
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.