Python - Перевірте, чи є слово в рядку


177

Я працюю з Python v2, і я намагаюся з’ясувати, чи можете ви сказати, чи є слово в рядку.

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

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

Дякуємо за будь-яку допомогу.

Відповіді:


350

Що не так:

if word in mystring: 
   print 'success'

103
як застереження, якщо у вас є рядок "паратифоз - це погано", і ви робите "якщо тиф" у "паратифоз поганий", ви отримаєте справжнє.
Девід Нельсон

3
Хтось знає, як подолати цю проблему?
користувач2567857

4
@ user2567857, регулярні вирази - див. відповідь Х'ю Ботвелл.
Марк Райкок

4
if (word1 у mystring та word2 у mystring)
louie mcconnell

2
Як це прийнята відповідь? !! Він просто перевіряє, чи з’являється послідовність символів (не слово) у рядку
pedram bashiri

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

але майте на увазі, що це відповідає послідовності символів, не обов'язково цілому слову - наприклад, 'word' in 'swordsmith'це правда. Якщо ви хочете співставити лише цілі слова, вам слід використовувати регулярні вирази:

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
Чи є дійсно швидкий метод пошуку кількох слів, скажімо, набір з кількох тисяч слів, без необхідності побудувати цикл для циклу, що проходить через кожне слово? У мене є мільйон речень і мільйон термінів, щоб шукати, щоб побачити, яке речення має відповідні слова. Наразі на обробку у мене потрібні дні, і я хочу знати, чи є швидший шлях.
Том

@ Спробуйте використати 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

Цей елегантний метод також найшвидший. Порівняно з підходами Х'ю Ботвелла та даSong:

>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) слів між ними. Ваш приклад не вдається лише тому, що ваш список слів містить двокрапку.
користувач200783

1
@JeffHeaton Вкотре цей метод є СПЕЦІФІЧНО для "Якщо ви хочете з’ясувати, чи є ціле слово в списку розділених пробілом слів", як чітко зазначив автор.
бітчітч

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

Це передбачає, що коми та інші розділові знаки вже викреслені.


Це рішення найкраще працювало в моєму випадку, оскільки я використовую токенізовані пробіли, розділені між собою.
Авіджіт

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

Використання регулярного вираження - це рішення, але воно є занадто складним для цього випадку.

Ви можете просто розділити текст на список слів. Використовувати сплати ( сепаратор , 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, з користю додавання загальних символів для розбиття на так, щоб у рядку типу "Перше: там .." можна було знайти слово "Перший". Зауважте, що @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.