Como verificar uma string para caracteres específicos? [fechadas]

182

Como posso verificar se uma string possui vários caracteres específicos usando o Python 2?

Por exemplo, dada a seguinte sequência:

Os criminosos roubaram US $ 1.000.000 em jóias.

Como detecto se ele possui cifrões ("$"), vírgulas (",") e números?

The Woo
fonte
1
Isso significa que todo caractere deve ser um desses, ou basta que um (ou todos) desses caracteres esteja presente na string? Eles precisam estar em alguma ordem (por exemplo: US $ 2,00) para que seja válido?
NullUserException 4/03/11
2
Assim como um tipo diferente de abordagem, not set(p).isdisjoint(set("0123456789$,"))onde pestá a string a ser testada.
Kevin

Respostas:

265

Assumindo que sua string é 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 assim por diante para outros personagens.

... ou

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

... ou

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

[Editar: adicionou as '$' in srespostas]

dappawit
fonte
20
s.find('$')!=-1=> '$' in s:-)
Jochen Ritzel 4/11/11
Existe alguma razão em particular pela qual o valor em não encontrado foi mantido -1 e não 0?
akki
2
@akki não encontrado é -1 porque 0 é o índice do primeiro caractere em uma string. Assim, "abc" .find ('a') = 0. Seria ambíguo se 0 também fosse o valor não encontrado.
Lemiant
1
Eu gosto dessa última versão usando any(). Existe uma maneira de se referir ao caractere encontrado cem um estilo pitônico (parece ter apenas um escopo dentro dele any()) ou eu precisaria tornar a pesquisa de vários caracteres mais explícita?
Jens
3
O segundo exemplo está quebrado: o regex precisa ter colchetes r'[\d\$,]'para que ele corresponda a qualquer um desses caracteres e else:falta o ponto e vírgula no final.
bjnord
23

O usuário Jochen Ritzel disse isso em um comentário para responder a esta pergunta do usuário dappawit. Deve funcionar:

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

'1', '2' etc. devem ser substituídos pelos caracteres que você está procurando.

Consulte esta página na documentação do Python 2.7 para obter mais informações sobre strings, incluindo sobre o uso do métodoin operador para testes de substring.

Atualização: faz o mesmo trabalho que minha sugestão acima com menos repetições:

# 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
fonte
+1 é mais compacto que vários .find () e é bom, desde que o número de caracteres pesquisados ​​seja baixo. Porém, não precisa dos parênteses.
21413 Sean
1
@Sean Sobre os parênteses: eu sei, porém é mais fácil para mim sempre usá-los, do que sempre lembrar da ordem de precedência :-).
Abbafei
11

Comparação rápida de horários em resposta à postagem de 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))

Resultado:

Func1 Time: 0.0737484362111
Func2 Time: 0.0125144964371

Portanto, o código é mais compacto com qualquer, mas mais rápido com o condicional.


EDIT: TL; DR - Para seqüências longas, if-then ainda é muito mais rápido que qualquer outro!

Decidi comparar o tempo para uma longa sequência aleatória com base em alguns dos pontos válidos levantados nos comentários:

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

Resultado:

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

If-then é quase uma ordem de magnitude mais rápida que qualquer outra!

Jesuisme
fonte
1
exatamente o que eu queria saber :-)
Lars
1
Alguém capaz de explicar por que o condicional é muito mais rápido do que usar algum?
21418 Josh
@ Josh provavelmente é porque é mais simples. O Func1 usa compreensão de lista explodida, tornando-o automaticamente mais complexo para coisas simples. Mas para 1000 caracteres, ele pode muito bem ser mais rápido usar Func1
Hack5
@ Hack5 suponha que phraseuma string com alfabetos de A a Z e eu quero imprimir quais alfabetos não estão presentes na string juntos será any()melhor? ou existe alguma maneira curta de verificar?
Avishek Datta Ray
@ Barefaced Nua nesse tipo de nível, escolha o que parecer melhor. A velocidade provavelmente não importa, a menos que você está controlando armas nucleares (no caso de você não deveria estar usando python qual)
Hack5
5

Isso testará se as strings são compostas de alguma combinação ou dígitos, o sinal de dólar e vírgulas. É isso que você está procurando?

importação re

s1 = 'Cadeia de teste'
s2 = '1234,12345 $'

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

if (regex.match (s1)):
   imprimir "s1 correspondente"
outro:
   a impressão "s1 não corresponde"

if (regex.match (s2)):
   imprimir "correspondência s2"
outro:
   a impressão "s2 não corresponde"
ajwood
fonte
Você não precisa escapar do $ se estiver em uma classe de personagem. Também isso corresponderá 'testing $tring', o que não acho que seja algo que o OP queira que aconteça.
NullUserException 4/03/11
Se bem me lembro, não corresponderia 'testing $tring'se o matchmétodo for usado, somente se searchfor usado. Então eu acho que o código dele está bom.
Dappawit
@dappa Ele ainda vai corresponder '$string'embora
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 ("Caractere especial não espacial")

Nagaraj
fonte
1
Você poderia fornecer um pouco mais de contexto à sua resposta.
brass monkey
verificação do tipo de caracteres presentes em uma string: isalnum (): Retorna True se todos os caracteres são alfanuméricos (a a z, A a Z, 0 a9) isalpha (): Retorna True se todos os caracteres são apenas símbolos do alfabeto (a a z, A a Z), isdigit (): Retorna True se todos os caracteres são apenas dígitos (0 a 9) islower (): Retorna True se todos os caracteres são símbolos do alfabeto em minúsculas isupper (): Retorna True se todos os caracteres são símbolos do alfabeto em maiúsculas istitle (): Retorna verdadeiro se string é no título caso isspace (): Retorna verdadeiro se string contém apenas espaços @LazerBass
Nagaraj