Python - Word'ün bir dizede olup olmadığını kontrol et


177

Python v2 ile çalışıyorum ve bir kelimenin bir dizede olup olmadığını söyleyebilir misiniz öğrenmeye çalışıyorum.

.Find kullanarak, dize kelime olup olmadığını belirleme hakkında bazı bilgiler bulduk, ancak bir IF deyimi yapmanın bir yolu var. Aşağıdaki gibi bir şey istiyorum:

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

Herhangi bir yardım için teşekkürler.

Yanıtlar:


350

Sorun nedir:

if word in mystring: 
   print 'success'

103
bir uyarı olarak, "paratifoit kötü" bir dizeniz varsa ve "paratifoit kötü" bir "tifo" yaparsanız bir doğru elde edersiniz.
David Nelson

3
Bu sorunun üstesinden nasıl geleceğini bilen var mı?
user2567857

4
@ user2567857, düzenli ifadeler - Hugh Bothwell'in cevabına bakınız.
Mark Rajcok

4
if (mystring içinde word1 ve mystring içinde word2)
louie mcconnell

2
Bu kabul edilen cevap nasıl? !! Sadece bir dizede bir karakter dizisinin (bir kelime değil) görünüp görünmediğini kontrol eder
pedram bashiri

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

ancak bunun bir karakter dizisiyle eşleştiğini, mutlaka tam bir kelime değil, örneğin 'word' in 'swordsmith'Doğru olduğunu unutmayın. Yalnızca tüm kelimeleri eşleştirmek istiyorsanız, düzenli ifadeler kullanmalısınız:

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
Her kelimeden geçen bir for döngüsü oluşturmak zorunda kalmadan, birkaç bin kelimelik bir dizi gibi, birden fazla kelime aramak için gerçekten hızlı bir yöntem var mı? Bir milyon cümleyim ve hangi cümlenin hangi eşleşen kelimelere sahip olduğunu görmek için aramak için bir milyon terim var. Şu anda işlenmem günler alıyor ve daha hızlı bir yol olup olmadığını bilmek istiyorum.
Tom

@Tom python regex yerine grep kullanmaya çalışın
El Ruso

kılıç ustası için p1
Robino

İstisnaları nasıl ele alırsınız, örneğin sözcük dizede bulunmadığında?
FaCoffee

1
@FaCoffee: dize bulunamazsa işlev Yok değerini döndürür (yukarıdaki son örneğe bakın).
Hugh Bothwell

48

Bir kelimenin tamamını boşlukla ayrılmış bir kelime listesinde olup olmadığını öğrenmek istiyorsanız, şunu kullanın:

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

Bu zarif yöntem de en hızlısıdır. Hugh Bothwell ve daSong'un yaklaşımlarıyla karşılaştırıldığında:

>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

Düzenleme: Python 3.6+ için bu fikir üzerinde hafif bir varyant, aynı derecede hızlı:

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

3
Bu benim en sevdiğim cevap :)
IanS

Kabul ediyorum, ancak en hızlı çözüm re.compile gibi davayı görmezden gelmiyor (... öyle
Michael Smith

7
Bunun birkaç sorunu vardır: (1) Sondaki kelimeler (2) Baştaki kelimeler (3) benzeri kelimelercontains_word("says", "Simon says: Don't use this answer")
Martin Thoma

@MartinThoma - Belirtildiği gibi, bu yöntem özellikle "bir sözcüğün boşlukla ayrılmış sözcükler listesinde olup olmadığını" bulmak içindir. Bu durumda, iyi çalışır: (1) Sondaki kelimeler (2) Baştaki kelimeler (3) arasındaki kelimeler. Örneğiniz yalnızca kelime listenizde iki nokta üst üste bulunduğundan başarısız olur.
user200783

1
@JeffHeaton Bir kez daha, bu yöntem, yazarın açıkça belirttiği gibi, "Bütün bir kelimenin boşlukla ayrılmış bir kelime listesinde olup olmadığını öğrenmek istiyorsanız" için bir kez daha özeldir.
bitwitch

17

find, arama öğesinin bulunduğu dizini temsil eden bir tamsayı döndürür. Bulunmazsa -1 döndürür.

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

Dizeyi kelimelere bölebilir ve sonuç listesini kontrol edebilirsiniz.

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

3
Düzenleme bağlantısını kullanarak bu kodun nasıl çalıştığını açıklayın ve sadece kodu vermeyin, çünkü bir açıklama gelecekteki okuyuculara yardımcı olma olasılığı daha yüksektir.
Jed Fox

1
Bu, tüm kelimeyi eşleştirmek için gerçek cevap olmalıdır.
Kaushik NP

10

Bu küçük işlev, verilen metindeki tüm arama kelimelerini karşılaştırır. Tüm arama sözcükleri metinde bulunursa, aramanın uzunluğunu döndürür veya Falsebaşka bir şekilde döndürür.

Ayrıca unicode dize aramayı da destekler.

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

kullanımı:

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

8

Bir karakter dizisini eşleştirmek yeterli değilse ve tüm kelimeleri eşleştirmeniz gerekiyorsa, işin yapılmasını sağlayan basit bir işlev. Temel olarak gerekli yerlerde boşluk ekler ve dizede bunu arar:

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

Bu, virgüllerin ve diğer noktalama işaretlerinin zaten kaldırıldığını varsayar.


Bu çözüm, tokenize alanla ayrılmış dizeler kullandığım için en iyi şekilde çalıştı.
Avijit

4

Bir kelime istiyor ve bir dize değil gibi, önek / soneklere duyarlı olmayan ve büyük / küçük harf görmezden gelir bir çözüm sunmak istiyorum:

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

Kelimeleriniz regex özel karakterleri (örneğin +) içeriyorsa ,re.escape(word)


3

Uzun bir dizede bulmamız gereken tam kelimeyi kontrol etmenin gelişmiş yolu:

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

Normal ifade kullanmak bir çözümdür, ancak bu durum için çok karmaşıktır.

Metni sözcük listesine ayırabilirsiniz. Bunun için split ( ayırıcı , num ) yöntemini kullanın . Ayırıcı olarak ayırıcı kullanarak dizedeki tüm sözcüklerin listesini döndürür . Eğer ayırıcı tüm boşluk üzerinde böler belirtilmemiş olan (isteğe size bölmeleri sayısını sınırlayabilir num ).

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

Bu, virgül vb. İçeren dize için çalışmaz. Örneğin:

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

Ayrıca tüm virgüllere vb. Bölmek istiyorsanız, şöyle ayırıcı bağımsız değişkenini kullanın :

# 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
Bu iyi bir çözümdür ve @Corvax'a benzer, "İlk: orada .." gibi bir dizede "İlk" kelimesinin bulunabilmesi için ortak karakterler eklemenin yararıdır. @Tstempko'nun ek karakterlere ":" eklemediğini unutmayın. İsterim :). Ayrıca, arama büyük / küçük harfe duyarlı değilse, bölünmeden önce hem word hem de dize üzerinde .lower () kullanmayı düşünün. mystring.lower().split()ve word.lower() bunun da normal ifade örneğinden daha hızlı olduğunu düşünüyorum.
beauk

0

"Word" den önce ve sonra bir boşluk ekleyebilirsiniz.

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

Bu şekilde "word" den önce ve sonra boşluk arar.

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

2
Peki ya kelime cümlenin başında ya da sonundaysa (boşluk yok)
MikeL
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.