Come controllare una stringa per caratteri specifici? [chiuso]


182

Come posso verificare se una stringa contiene diversi caratteri specifici usando Python 2?

Ad esempio, data la seguente stringa:

I criminali hanno rubato $ 1,000,000 in gioielli.

Come posso rilevare se ha segni di dollaro ("$"), virgole (",") e numeri?


1
Significa che ogni personaggio dovrebbe essere uno di questi o è sufficiente che uno (o tutti) di questi personaggi sia presente nella stringa? Devono essere in un certo ordine (es: $ 2,00) perché siano validi?
NullUserException

2
Proprio come un diverso tipo di approccio, not set(p).isdisjoint(set("0123456789$,"))dov'è pla stringa da testare.
Kevin,

Risposte:


265

Supponendo che la tua stringa sia 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

E così via per altri personaggi.

... o

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

... o

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

[Modifica: aggiunte le '$' in srisposte]


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

C'è qualche motivo particolare per cui il valore su non trovato è stato mantenuto -1 e non 0 ??
Akki

2
@akki non trovato è -1 perché 0 è l'indice del primo carattere in una stringa. Pertanto "abc" .find ('a') = 0. Sarebbe ambiguo se anche 0 fosse il valore non trovato.
lemiant

1
Mi piace usare l'ultima versione any(). Esiste un modo per fare riferimento al personaggio trovato cin uno stile pitone (sembra che abbia any()solo uno scopo), o dovrei rendere più esplicita la ricerca di più caratteri?
Jens,

3
Il secondo esempio è spezzato: la regex deve avere parentesi in r'[\d\$,]'modo che corrisponda a uno di quei personaggi e alla fine else:mancano i due punti.
bjnord,

23

l'utente Jochen Ritzel ha detto questo in un commento a una risposta a questa domanda dell'utente dappawit. Dovrebbe funzionare:

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

'1', '2', ecc. Devono essere sostituiti con i caratteri che stai cercando.

Vedere questa pagina nella documentazione di Python 2.7 per alcune informazioni sulle stringhe, incluso l'uso indell'operatore per i test di sottostringa.

Aggiornamento: fa lo stesso lavoro del mio suggerimento sopra con meno ripetizioni:

# 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 è più compatto di più .find () e va bene finché il numero di caratteri cercato è basso. Non ha bisogno delle parentesi però.
Sean,

1
@Sean Informazioni sulle parentesi: lo so, tuttavia è più facile per me usarle sempre, piuttosto che ricordare sempre l'ordine di precedenza :-).
Abbafei,

11

Confronto veloce dei tempi in risposta al post di 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))

Produzione:

Func1 Time: 0.0737484362111
Func2 Time: 0.0125144964371

Quindi il codice è più compatto con qualsiasi, ma più veloce con il condizionale.


EDIT: TL; DR - Per stringhe lunghe, if-then è ancora molto più veloce di qualsiasi altro!

Ho deciso di confrontare i tempi per una lunga stringa casuale basata su alcuni dei punti validi sollevati nei commenti:

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

Produzione:

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

If-then è quasi un ordine di grandezza più veloce di qualsiasi altro!


1
esattamente quello che volevo sapere :-)
Lars

1
Qualcuno in grado di spiegare perché il condizionale è molto più veloce dell'uso?
Josh,

@Josh probabilmente è perché è più semplice. Func1 utilizza la comprensione di elenchi esplosi, quindi è automaticamente più complesso per cose semplici. Ma per 1000 caratteri, potrebbe essere più veloce usare Func1
Hack5 il

@ Hack5 supponiamo che phraseuna stringa con alfabeti dalla A alla Z e che voglio stampare quali alfabeti non sono presenti nella stringa insieme sarà any()migliore? o c'è un modo breve per controllare?
Avishek Datta Ray

@Barefaced Nudo a quel tipo di livello, scegli quello che sembra più bello. Probabilmente la velocità non ha importanza, a meno che tu non stia controllando armi nucleari (nel qual caso non dovresti usare Python)
Hack5

5

Questo verificherà se le stringhe sono composte da una combinazione o cifre, dal simbolo del dollaro e da una virgola. È quello che stai cercando?

import re

s1 = 'Stringa di prova'
s2 = '1234.12345 $'

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

if (regex.match (s1)):
   stampa "s1 abbinato"
altro:
   stampa "s1 non corrisponde"

if (regex.match (s2)):
   stampa "s2 abbinato"
altro:
   stampa "s2 non corrisponde"

Non devi scappare da $ se è in una classe di personaggi. Anche questo corrisponderà 'testing $tring', che non credo sia qualcosa che l'OP vuole accadere.
NullUserException

Se ricordo bene, non corrisponderebbe 'testing $tring'se matchviene utilizzato il metodo, solo se searchviene utilizzato. Quindi penso che il suo codice vada bene.
dappawit,

@dappa Abbinerà comunque '$string'comunque
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 ("Carattere speciale non spaziale")


1
Potresti fornire un po 'più contesto alla tua risposta.
scimmia d'ottone,

controllo del tipo di caratteri presenti in una stringa: isalnum (): restituisce True se tutti i caratteri sono alfanumerici (dalla a alla Z, dalla A alla Z, da 0 a 9) isalpha (): restituisce True se tutti i caratteri sono solo simboli alfabetici (dalla a alla z, Dalla A alla Z), isdigit (): restituisce True se tutti i caratteri sono solo cifre (da 0 a 9) islower (): Restituisce True se tutti i caratteri sono minuscoli simboli dell'alfabeto isupper (): Restituisce True se tutti i caratteri sono in maiuscolo simboli aplhabet istitle (): restituisce True se la stringa è nel case del titolo isspace (): Restituisce True se la stringa contiene solo spazi @LazerBass
Nagaraj
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.