Python ตรวจสอบว่า Word อยู่ในสตริงหรือไม่


177

ฉันทำงานกับ Python v2 และฉันพยายามค้นหาว่าคุณสามารถบอกได้ไหมว่าคำนั้นอยู่ในสตริง

ฉันพบข้อมูลบางอย่างเกี่ยวกับการระบุว่าคำนั้นอยู่ในสตริงหรือไม่โดยใช้. find แต่มีวิธีทำคำสั่ง IF ฉันต้องการมีสิ่งต่อไปนี้:

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

ขอบคุณสำหรับความช่วยเหลือ

คำตอบ:


350

เกิดอะไรขึ้นกับ:

if word in mystring: 
   print 'success'

103
เช่นเดียวกับข้อควรระวังถ้าคุณมีสตริง "ไข้รากสาดเทียมไม่ดี" และคุณทำถ้า "ไทฟอยด์" ใน "ไข้รากสาดเทียมไม่ดี" คุณจะได้รับจริง
เดวิดเนลสัน

3
ใครรู้วิธีเอาชนะปัญหานี้
2567857

4
@ user2567857 การแสดงออกปกติ - ดูคำตอบของ Hugh Bothwell
Mark Rajcok

4
if (word1 in mystring และ word2 in mystring)
louie mcconnell

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
มีวิธีที่รวดเร็วมากในการค้นหาคำหลายคำพูดหนึ่งพันคำหลายพันคำโดยไม่ต้องสร้างลูปสำหรับแต่ละคำ? ฉันมีหนึ่งล้านประโยคและอีกหนึ่งล้านคำที่ต้องค้นหาเพื่อดูว่าประโยคใดมีคำที่ตรงกัน ขณะนี้ใช้เวลาหลายวันในการประมวลผลและฉันต้องการทราบว่ามีวิธีที่เร็วกว่านี้หรือไม่
Tom

@Tom ลองใช้ grep แทน python regex
El Ruso

p1 สำหรับ swordsmith
Robino

คุณจะจัดการกับข้อยกเว้นเช่นเมื่อไม่พบคำในสตริงได้อย่างไร
FaCoffee

1
@FaCoffee: หากไม่พบสตริงฟังก์ชันจะส่งคืน None (ดูตัวอย่างล่าสุดด้านบน)
Hugh Bothwell

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

วิธีการอันงดงามนี้ยังเร็วที่สุด เปรียบเทียบกับแนวทางของ Hugh Bothwell และ 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

แก้ไข:ตัวแปรเล็กน้อยสำหรับแนวคิดนี้สำหรับ Python 3.6+ เร็วพอ ๆ กัน:

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

3
นี่คือคำตอบที่ชื่นชอบของฉัน :)
IANS

ฉันเห็นด้วย แต่วิธีแก้ปัญหาที่เร็วที่สุดไม่ได้เพิกเฉยต่อกรณีเช่น re.compile (... ทำ.
Michael Smith

7
สิ่งนี้มีปัญหาหลายอย่าง: (1) คำท้าย (2) คำที่จุดเริ่มต้น (3) คำที่อยู่ในระหว่างชอบcontains_word("says", "Simon says: Don't use this answer")
Martin Thoma

@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
โปรดใช้ลิงก์แก้ไขอธิบายวิธีการทำงานของรหัสนี้และไม่เพียง แต่ให้รหัสเนื่องจากคำอธิบายมีแนวโน้มที่จะช่วยผู้อ่านในอนาคต
Jed Fox

1
นี่ควรเป็นคำตอบที่แท้จริงสำหรับการจับคู่ทั้งคำ
Kaushik NP

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()

หากคำพูดของคุณอาจมีตัวอักษรพิเศษ regex (เช่น+) คุณก็จำเป็นต้องใช้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

การใช้ regex เป็นวิธีแก้ปัญหา แต่มันซับซ้อนเกินไปสำหรับกรณีนั้น

คุณสามารถแยกข้อความออกเป็นรายการคำศัพท์ได้ ใช้เมธอด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() ฉันคิดว่านี่ยังเร็วกว่าตัวอย่างของ regex
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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.