Python - Kiểm tra xem Word có trong chuỗi không


177

Tôi đang làm việc với Python v2 và tôi đang cố gắng tìm hiểu xem bạn có thể biết liệu một từ có nằm trong chuỗi không.

Tôi đã tìm thấy một số thông tin về việc xác định nếu từ đó có trong chuỗi - sử dụng .find, nhưng có cách nào để thực hiện một câu lệnh IF. Tôi muốn có một cái gì đó như sau:

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

Cảm ơn vì bất kì sự giúp đỡ.

Câu trả lời:


349

Co chuyện gi sai vơi:

if word in mystring: 
   print 'success'

103
cũng như một sự thận trọng, nếu bạn có một chuỗi "paratyphoid là xấu" và bạn làm một "thương hàn" trong "paratyphoid là xấu", bạn sẽ nhận được một sự thật.
David Nelson

3
Bất cứ ai cũng biết làm thế nào để khắc phục vấn đề này?
dùng2567857

4
@ user2567857, các biểu thức chính quy - xem câu trả lời của Hugh Bothwell.
Mark Rajcok

4
if (word1 in mystring và word2 in mystring)
louie mcconnell

2
Làm thế nào đây là câu trả lời được chấp nhận? !! Nó chỉ kiểm tra xem một chuỗi các ký tự (không phải là một từ) xuất hiện trong một chuỗi
pedram bashiri

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

nhưng hãy nhớ rằng điều này khớp với một chuỗi các ký tự, không nhất thiết phải là toàn bộ từ - ví dụ, 'word' in 'swordsmith'là True. Nếu bạn chỉ muốn khớp toàn bộ các từ, bạn nên sử dụng các cụm từ thông dụng:

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
Có một phương pháp thực sự nhanh chóng để tìm kiếm nhiều từ, nói một tập hợp vài nghìn từ, mà không phải xây dựng một vòng lặp for đi qua mỗi từ? Tôi có một triệu câu và một triệu thuật ngữ để tìm kiếm để xem câu nào có từ phù hợp. Hiện tại tôi đang mất nhiều ngày để xử lý và tôi muốn biết liệu có cách nào nhanh hơn không.
Tom

@Tom hãy thử sử dụng grep thay vì regex python
El Ruso

p1 cho kiếm sĩ
Robino

Làm thế nào để bạn xử lý các trường hợp ngoại lệ, ví dụ khi không tìm thấy từ trong chuỗi?
FaCoffee

1
@FaCoffee: nếu không tìm thấy chuỗi, hàm sẽ trả về Không (xem ví dụ cuối ở trên).
Hugh Bothwell

48

Nếu bạn muốn tìm hiểu xem toàn bộ một từ có nằm trong danh sách các từ được phân tách bằng dấu cách không, chỉ cần sử dụng:

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

Phương pháp thanh lịch này cũng là nhanh nhất. So với cách tiếp cận của Hugh Bothwell và 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

Chỉnh sửa: Một biến thể nhỏ trên ý tưởng này cho Python 3.6+, nhanh không kém:

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

3
Đây là câu trả lời yêu thích của tôi :)
IanS

Tôi đồng ý, nhưng giải pháp nhanh nhất không bỏ qua trường hợp như re.compile (... hiện.
Michael Smith

7
Điều này có một số vấn đề: (1) Từ ở cuối (2) Từ ở đầu (3) từ ở giữacontains_word("says", "Simon says: Don't use this answer")
Martin Thoma

@MartinThoma - Như đã nêu, phương pháp này dành riêng cho việc tìm hiểu "liệu toàn bộ một từ có nằm trong danh sách các từ được phân tách bằng dấu cách không". Trong tình huống đó, nó hoạt động tốt đối với: (1) Từ ở cuối (2) Từ ở đầu (3) từ ở giữa. Ví dụ của bạn chỉ thất bại vì danh sách các từ của bạn bao gồm dấu hai chấm.
user200783

1
@JeffHeaton Một lần nữa, phương pháp này ĐẶC ​​BIỆT cho "Nếu bạn muốn tìm hiểu xem toàn bộ một từ có nằm trong danh sách các từ được phân tách bằng dấu cách không", như tác giả đã nêu rõ.
bitwitch

17

find trả về một số nguyên biểu thị chỉ mục nơi tìm thấy mục tìm kiếm. Nếu không tìm thấy, nó trả về -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

Bạn có thể chia chuỗi thành các từ và kiểm tra danh sách kết quả.

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

3
Vui lòng sử dụng liên kết chỉnh sửa giải thích cách mã này hoạt động và không chỉ cung cấp mã, vì một lời giải thích có nhiều khả năng giúp người đọc trong tương lai.
Jed Fox

1
Đây phải là câu trả lời thực tế cho phù hợp với toàn bộ từ.
NP Kaushik

10

Hàm nhỏ này so sánh tất cả các từ tìm kiếm trong văn bản đã cho. Nếu tất cả các từ tìm kiếm được tìm thấy trong văn bản, trả về thời lượng tìm kiếm, hoặc Falsenếu không.

Cũng hỗ trợ tìm kiếm chuỗi 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

sử dụng:

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

8

Nếu khớp một chuỗi các ký tự là không đủ và bạn cần khớp toàn bộ các từ, thì đây là một chức năng đơn giản giúp hoàn thành công việc. Về cơ bản, nó nối thêm các khoảng trống khi cần thiết và tìm kiếm trong chuỗi đó:

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

Điều này giả định rằng dấu phẩy và dấu chấm câu khác đã bị loại bỏ.


Giải pháp này hoạt động tốt nhất cho trường hợp của tôi vì tôi đang sử dụng các chuỗi phân tách không gian được mã hóa.
Avijit

4

Vì bạn đang yêu cầu một từ chứ không phải một chuỗi, tôi muốn trình bày một giải pháp không nhạy cảm với tiền tố / hậu tố và bỏ qua trường hợp:

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

Nếu từ của bạn có thể chứa các ký tự đặc biệt regex (chẳng hạn như +), thì bạn cầnre.escape(word)


3

Cách nâng cao để kiểm tra từ chính xác mà chúng ta cần tìm trong một chuỗi dài:

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

Sử dụng regex là một giải pháp, nhưng nó quá phức tạp cho trường hợp đó.

Bạn chỉ có thể chia văn bản thành danh sách các từ. Sử dụng phương pháp split ( separator , num ) cho điều đó. Nó trả về một danh sách tất cả các từ trong chuỗi, sử dụng dấu phân cách làm dấu phân cách. Nếu dấu phân cách không được chỉ định, nó sẽ phân tách trên tất cả các khoảng trắng (tùy ý bạn có thể giới hạn số lần chia thành num ).

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

Điều này sẽ không hoạt động cho chuỗi với dấu phẩy, v.v. Ví dụ:

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

Nếu bạn cũng muốn phân tách trên tất cả các dấu phẩy, v.v. hãy sử dụng đối số dấu phân cách như sau:

# 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
Đây là một giải pháp tốt và tương tự như @Corvax, với lợi ích là thêm các ký tự phổ biến để phân tách để trong một chuỗi như "First: there ..", từ "First" có thể được tìm thấy. Lưu ý rằng @tstempko không bao gồm ":" trong các ký tự bổ sung. Tôi sẽ :). Ngoài ra, nếu tìm kiếm không phân biệt chữ hoa chữ thường, hãy xem xét sử dụng .lower () trên cả từ và chuỗi trước khi phân tách. mystring.lower().split()word.lower() tôi nghĩ rằng điều này cũng nhanh hơn ví dụ regex.
beauk

0

Bạn chỉ có thể thêm một khoảng trắng trước và sau "từ".

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

Bằng cách này, nó tìm kiếm không gian trước và sau "từ".

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

2
Nhưng chuyện gì sẽ xảy ra nếu từ đó ở đầu hoặc cuối câu (không có khoảng
trắng
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.