Bagaimana cara memeriksa string untuk karakter tertentu? [Tutup]

182

Bagaimana saya bisa memeriksa apakah string memiliki beberapa karakter spesifik di dalamnya menggunakan Python 2?

Misalnya, diberikan string berikut:

Para penjahat mencuri perhiasan senilai $ 1.000.000.

Bagaimana saya mendeteksi jika ada tanda dolar ("$"), koma (","), dan angka?

Woo
sumber
1
Apakah itu berarti setiap karakter seharusnya menjadi salah satu dari ini, atau apakah cukup bahwa satu (atau semua) karakter ini ada dalam string? Apakah mereka harus dalam urutan tertentu (misalnya: $ 2,00) agar valid?
NullUserException
2
Sama seperti jenis pendekatan yang berbeda, di not set(p).isdisjoint(set("0123456789$,"))mana pstring untuk menguji.
Kevin

Jawaban:

265

Dengan asumsi string Anda adalah 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

Dan seterusnya untuk karakter lain.

... atau

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

... atau

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

[Sunting: menambahkan '$' in sjawaban]

dappawit
sumber
20
s.find('$')!=-1=> '$' in s:-)
Jochen Ritzel
Apakah ada alasan khusus mengapa nilai pada tidak ditemukan disimpan -1 dan bukan 0 ??
akki
2
@akki tidak ditemukan adalah -1 karena 0 adalah indeks karakter pertama dalam sebuah string. Jadi "abc" .find ('a') = 0. Akan ambigu jika 0 juga bukan nilai yang ditemukan.
lemiant
1
Saya suka menggunakan versi terakhir any(). Apakah ada cara untuk merujuk ke karakter yang ditemukan cdalam gaya pythonic (sepertinya hanya dibatasi di dalamnya any()), atau akankah saya perlu membuat pencarian untuk beberapa karakter lebih eksplisit?
Jens
3
Contoh kedua rusak: Regex harus memiliki tanda kurung r'[\d\$,]'sehingga cocok dengan salah satu karakter tersebut, dan yang else:hilang pada titik dua di ujungnya.
bjnord
23

pengguna Jochen Ritzel mengatakan ini dalam komentar untuk jawaban atas pertanyaan ini dari pengguna dappawit. Itu harus bekerja:

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

'1', '2', dll. Harus diganti dengan karakter yang Anda cari.

Lihat halaman ini dalam dokumentasi Python 2.7 untuk beberapa informasi tentang string, termasuk tentang penggunaan inoperator untuk pengujian substring.

Pembaruan: Ini melakukan pekerjaan yang sama dengan saran saya di atas dengan pengulangan yang lebih sedikit:

# 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
Abbafei
sumber
+1 ini lebih ringkas daripada beberapa .find (), dan tidak masalah selama jumlah karakter yang dicari rendah. Tidak membutuhkan tanda kurung.
Sean
1
@Sean Tentang tanda kurung: Saya tahu, namun lebih mudah bagi saya untuk selalu menggunakannya, daripada selalu mengingat urutan yang diutamakan :-).
Abbafei
11

Perbandingan cepat waktu dalam menanggapi posting oleh Abbafei:

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

Keluaran:

Func1 Time: 0.0737484362111
Func2 Time: 0.0125144964371

Jadi kodenya lebih kompak dengan apa saja, tetapi lebih cepat dengan kondisional.


EDIT: TL; DR - Untuk string panjang, jika-maka masih jauh lebih cepat daripada yang lainnya!

Saya memutuskan untuk membandingkan waktu untuk string acak panjang berdasarkan pada beberapa poin valid yang muncul dalam komentar:

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

Keluaran:

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

Jika-maka hampir urutan besarnya lebih cepat daripada yang lain!

Jesuisme
sumber
1
persis apa yang ingin saya ketahui :-)
Lars
1
Adakah yang bisa menjelaskan mengapa persyaratannya jauh lebih cepat daripada menggunakan?
Josh
@Josh mungkin itu karena lebih sederhana. Func1 menggunakan pemahaman daftar meledak sehingga secara otomatis mungkin lebih kompleks untuk hal-hal sederhana. Tetapi untuk 1000 karakter, mungkin lebih cepat menggunakan Func1
Hack5
@ Hack5 misalkan phrasestring dengan huruf dari A ke Z dan saya ingin mencetak huruf mana yang tidak hadir dalam string yang akan any()lebih baik? atau adakah cara pendek untuk memeriksa?
Avishek Datta Ray
@Barefaced Bare pada level seperti itu, pilih yang mana yang terlihat lebih bagus. Kecepatannya mungkin tidak masalah, kecuali Anda mengendalikan nuklir (dalam hal ini Anda tidak boleh menggunakan python)
Hack5
5

Ini akan menguji apakah string terdiri dari beberapa kombinasi atau digit, tanda dolar, dan koma. Itukah yang kamu cari?

impor ulang

s1 = 'Menguji string'
s2 = '1234,12345 $'

regex = re.compile ('[0-9, $] + $')

if (regex.match (s1)):
   cetak "s1 cocok"
lain:
   cetak "s1 tidak cocok"

if (regex.match (s2)):
   cetak "s2 cocok"
lain:
   cetak "s2 tidak cocok"
ajwood
sumber
Anda tidak perlu melarikan diri dari $ jika berada dalam kelas karakter. Juga ini akan cocok 'testing $tring', yang menurut saya bukan sesuatu yang OP inginkan untuk terjadi.
NullUserException
Jika saya ingat dengan benar, itu tidak akan cocok 'testing $tring'jika matchmetode ini digunakan, hanya jika searchdigunakan. Jadi saya pikir kodenya baik-baik saja.
dappawit
@dappa Ini masih akan cocok '$string'meskipun
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")   

lain:
cetak ("Karakter Khusus Non Space")

Nagaraj
sumber
1
Bisakah Anda memberikan sedikit lebih banyak konteks untuk jawaban Anda.
Monyet kuningan
memeriksa tipe karakter yang ada dalam string: isalnum (): Mengembalikan Benar jika semua karakter alfanumerik (a ke z, A ke Z, 0 hingga 9) isalpha (): Mengembalikan Benar jika semua karakter hanya simbol alfabet (a ke z, A ke Z), isdigit (): Returns True jika semua karakter hanya digit (0 hingga 9) islower (): Returns True jika semua karakter adalah simbol huruf kecil dengan huruf isupper (): Mengembalikan True jika semua karakter adalah simbol huruf besar huruf besar istitle (): Mengembalikan True jika string dalam judul case isspace (): Returns True jika string hanya berisi spasi @LazerBass
Nagaraj