Bir dizeyi belirli karakterler için nasıl kontrol edebilirim? [kapalı]


182

Python 2'yi kullanarak bir dizenin içinde birkaç belirli karakter olup olmadığını nasıl kontrol edebilirim?

Örneğin, aşağıdaki dize verildiğinde:

Suçlular mücevherleri 1.000.000 dolar çaldılar.

Dolar işareti ("$"), virgül (",") ve sayıları olup olmadığını nasıl tespit edebilirim?


1
Bu, her karakterin bunlardan biri olması gerektiği anlamına mı geliyor, yoksa bu karakterlerden birinin (veya hepsinin) dizede mevcut olması yeterli mi? Geçerli olması için bir sırada olmaları gerekiyor mu (ör: 2,00 $)?
NullUserException

2
Farklı bir yaklaşım gibi, test edilecek dize not set(p).isdisjoint(set("0123456789$,"))nerede p.
Kevin

Yanıtlar:


265

Dizenizi varsayalım s:

'$' in s        # found
'$' not in s    # not found

# original answer given, but less Pythonic than the above...
s.find('$')==-1 # not found
s.find('$')!=-1 # found

Ve diğer karakterler için.

... veya

pattern = re.compile(r'\d\$,')
if pattern.findall(s):
    print('Found')
else
    print('Not found')

... veya

chars = set('0123456789$,')
if any((c in chars) for c in s):
    print('Found')
else:
    print('Not Found')

[Düzenle: '$' in scevapları ekledi ]


20
s.find('$')!=-1=> '$' in s:-)
Jochen Ritzel

Bulunamayan değerin 0 değil -1 olarak tutulmasının özel bir nedeni var mı?
akki

2
@akki bulunamadı -1, çünkü 0 bir dizedeki ilk karakterin dizinidir. Böylece "abc" .find ('a') = 0. 0 da bulunmayan değer olsaydı belirsiz olurdu.
2014'te

1
Ben bu son sürümü kullanarak seviyorum any(). Bulunan karaktere cbir pitonik tarzda başvurmak için bir yol var mı ( any()sadece içinde yer alıyor gibi görünüyor ), ya da ben birkaç karakter için arama daha açık yapmak gerekir?
Jens

3
İkinci örnek bozuldu: Normal ifadenin köşeli ayraç içermesi gerekir, r'[\d\$,]'böylece bu karakterlerden herhangi biriyle eşleşir else:ve sonunda iki nokta üst üste işareti eksiktir.
bjnord

23

kullanıcı Jochen Ritzel kullanıcı dappawit bu soruya bir cevap için bir yorumda söyledi. İşe yaramalı:

('1' in var) and ('2' in var) and ('3' in var) ...

'1', '2' vb. Aradığınız karakterlerle değiştirilmelidir.

Görmek inAlt dize testleri için operatörün kullanılması da dahil olmak üzere dizelerle ilgili bazı bilgiler için Python 2.7 belgelerindeki bu sayfaya .

Güncelleme: Bu, yukarıdaki önerimle aynı işi daha az tekrarlamayla yapıyor:

# When looking for single characters, this checks for any of the characters...
# ...since strings are collections of characters
any(i in '<string>' for i in '123')
# any(i in 'a' for i in '123') -> False
# any(i in 'b3' for i in '123') -> True

# And when looking for subsrings
any(i in '<string>' for i in ('11','22','33'))
# any(i in 'hello' for i in ('18','36','613')) -> False
# any(i in '613 mitzvahs' for i in ('18','36','613')) ->True

+1, bu birden çok .find () 'den daha küçüktür ve aranan karakter sayısı düşük olduğu sürece iyidir. Gerçi parantez gerekmez.
Sean

1
@Sean ebeveynler hakkında: Biliyorum, ancak her zaman bunları kullanmak benim için öncelik sırasını hatırlamaktan daha kolay :-).
Abbafei

11

Abbafei tarafından gönderilen mesaja yanıt olarak zamanlamaların hızlı bir şekilde karşılaştırılması:

import timeit

def func1():
    phrase = 'Lucky Dog'
    return any(i in 'LD' for i in phrase)

def func2():
    phrase = 'Lucky Dog'
    if ('L' in phrase) or ('D' in phrase):
        return True
    else:
        return False

if __name__ == '__main__': 
    func1_time = timeit.timeit(func1, number=100000)
    func2_time = timeit.timeit(func2, number=100000)
    print('Func1 Time: {0}\nFunc2 Time: {1}'.format(func1_time, func2_time))

Çıktı:

Func1 Time: 0.0737484362111
Func2 Time: 0.0125144964371

Yani kod herhangi biriyle daha kompakt, ancak koşullu ile daha hızlı.


EDIT: TL; DR - Uzun dizeler için, eğer öyleyse hala her zamankinden daha hızlı!

Yorumlarda ortaya çıkan bazı geçerli noktalara dayanarak uzun bir rastgele dize için zamanlamayı karşılaştırmaya karar verdim:

# Tested in Python 2.7.14

import timeit
from string import ascii_letters
from random import choice

def create_random_string(length=1000):
    random_list = [choice(ascii_letters) for x in range(length)]
    return ''.join(random_list)

def function_using_any(phrase):
    return any(i in 'LD' for i in phrase)

def function_using_if_then(phrase):
    if ('L' in phrase) or ('D' in phrase):
        return True
    else:
        return False

if __name__ == '__main__':
    random_string = create_random_string(length=2000)
    func1_time = timeit.timeit(stmt="function_using_any(random_string)",
                               setup="from __main__ import function_using_any, random_string",
                               number=200000)
    func2_time = timeit.timeit(stmt="function_using_if_then(random_string)",
                               setup="from __main__ import function_using_if_then, random_string",
                               number=200000)
    print('Time for function using any: {0}\nTime for function using if-then: {1}'.format(func1_time, func2_time))

Çıktı:

Time for function using any: 0.1342546
Time for function using if-then: 0.0201827

Eğer öyleyse neredeyse her zamankinden daha hızlı bir büyüklük sırasıdır!


1
tam olarak bilmek istediklerim :-)
Lars

1
Şartlı olanın neden kullanmaktan daha hızlı olduğunu açıklayan var mı?
Josh

@Josh muhtemelen daha basit olduğu için. Func1, patlatılmış liste kavrayışı kullanır, böylece basit şeyler için otomatik olarak daha karmaşık hale gelir. Ancak 1000 karakter için Func1
Hack5

@ Hack5 A'dan phraseZ'ye alfabe ile bir dize varsayalım ve ben hangi alfabe birlikte mevcut değil dize yazdırmak istiyorum kullanarak any()daha iyi olacak ? veya kontrol etmenin kısa bir yolu var mı?
Avishek Datta Ray

@Barefaced Bu seviyede bir seviyede çıplak, hangisi daha güzel görünüyorsa onu seç.
Nükleer

5

Bu, dizelerin bazı kombinasyon veya basamaklardan, dolar işaretinden ve virgüllerden oluşup oluşmadığını test eder. Aradığın şey bu mu?

yeniden içe aktar

s1 = 'Test dizesi'
s2 = '1234,12345 $'

regex = yeniden derleme ('[0-9, $] + $')

if (regex.match (s1)):
   "s1 eşleşti" yazdır
Başka:
   "s1 eşleşmedi" yazdır

eğer (normal ifade eşleşmesi (s2)):
   "s2 uyumlu" yazdır
Başka:
   yazdır "s2 eşleşmedi"

Bir karakter sınıfındaysa $ 'dan kaçmak zorunda değilsiniz. Bu da 'testing $tring'OP'nin gerçekleşmesini istediği bir şey olduğunu düşünmüyorum.
NullUserException

Doğru hatırlarsam 'testing $tring', matchyöntem kullanılırsa eşleşmez , yalnızca searchkullanılırsa. Bu yüzden kodunun iyi olduğunu düşünüyorum.
dappawit

@dappa Hala maç olacak '$string'olsa
NullUserException

-2
s=input("Enter any character:")   
if s.isalnum():   
   print("Alpha Numeric Character")   
   if s.isalpha():   
       print("Alphabet character")   
       if s.islower():   
         print("Lower case alphabet character")   
       else:   
         print("Upper case alphabet character")   
   else:   
     print("it is a digit")   
elif s.isspace():   
    print("It is space character")   

else:
print ("Boşluk Olmayan Özel Karakter")


1
Cevabınıza biraz daha bağlam verebilir misiniz?
pirinç maymunu

dizede mevcut olan karakter türlerini kontrol etme: isalnum (): Tüm karakterler alfasayısalsa (a'dan z'ye, A'dan Z'ye, 0'dan 9'a kadar) isalpha (): Tüm karakterler yalnızca alfabe sembolleri (a'dan z'ye, A - Z), isdigit (): Tüm karakterler yalnızca rakamsa (0 - 9) islower (): Tüm karakterler küçük harfli alfabe sembolleri isupper () ise True değerini döndürür: Tüm karakterler büyük harfli aplhabet sembolleri ise True döndürür istitle (): Dize başlık durumunda ise True döndürür isspace (): Dize yalnızca boşluk içeriyorsa True döndürür @LazerBass
Nagaraj
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.