¿Cómo verificar una cadena de caracteres específicos? [cerrado]


182

¿Cómo puedo verificar si una cadena tiene varios caracteres específicos usando Python 2?

Por ejemplo, dada la siguiente cadena:

Los delincuentes robaron $ 1,000,000 en joyas.

¿Cómo detecto si tiene signos de dólar ("$"), comas (",") y números?


1
¿Eso significa que se supone que cada personaje es uno de estos, o es suficiente que uno (o todos) de estos personajes estén presentes en la cadena? ¿Tienen que estar en algún orden (por ejemplo: $ 2,00) para que sea válido?
NullUserException

2
Solo como un tipo diferente de enfoque, ¿ not set(p).isdisjoint(set("0123456789$,"))dónde pestá la cadena para probar?
Kevin

Respuestas:


265

Asumiendo que su cadena es 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

Y así sucesivamente para otros personajes.

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

[Editar: agregó las '$' in srespuestas]


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

¿Hay alguna razón particular por la cual el valor de no encontrado se mantuvo -1 y no 0?
akki

2
@akki no encontrado es -1 porque 0 es el índice del primer carácter de una cadena. Por lo tanto, "abc" .find ('a') = 0. Sería ambiguo si 0 también fuera el valor no encontrado.
lemiant

1
Me gusta esa última versión usando any(). ¿Hay alguna manera de referirse al carácter encontrado cen un estilo pitónico (parece que solo tiene un alcance interno any()), o tendría que hacer que la búsqueda de varios caracteres sea más explícita?
Jens

3
El segundo ejemplo está roto: la expresión regular necesita tener corchetes r'[\d\$,]'para que coincida con cualquiera de esos caracteres, y else:le faltan dos puntos al final.
bjnord

23

el usuario Jochen Ritzel dijo esto en un comentario a una respuesta a esta pregunta del usuario dappawit. Deberia de funcionar:

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

'1', '2', etc. deben reemplazarse con los caracteres que está buscando.

Consulte esta página en la documentación de Python 2.7 para obtener información sobre cadenas, incluido el uso del inoperador para pruebas de subcadenas.

Actualización: esto hace el mismo trabajo que mi sugerencia anterior con menos repetición:

# 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 es más compacto que varios .find () y está bien siempre que el número de caracteres buscados sea bajo. Sin embargo, no necesita los paréntesis.
Sean

1
@Sean Acerca de los paréntesis: Lo sé, sin embargo, es más fácil para mí usarlos siempre que recordar siempre el orden de precedencia :-).
Abbafei

11

Comparación rápida de tiempos en respuesta a la publicación 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))

Salida:

Func1 Time: 0.0737484362111
Func2 Time: 0.0125144964371

Entonces el código es más compacto con cualquiera, pero más rápido con el condicional.


EDITAR: TL; DR - ¡Para cadenas largas, si-entonces sigue siendo mucho más rápido que cualquiera!

Decidí comparar el tiempo para una cadena larga aleatoria en función de algunos de los puntos válidos planteados en los comentarios:

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

Salida:

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

¡Si, entonces es casi un orden de magnitud más rápido que cualquiera!


1
exactamente lo que quería saber :-)
Lars

1
¿Alguien capaz de explicar por qué el condicional es mucho más rápido que usar cualquiera?
Josh

@ Josh probablemente sea porque es más simple. Func1 utiliza la comprensión de listas explotadas, por lo que automáticamente es mucho más compleja para las cosas simples. Pero para 1000 caracteres, puede ser más rápido usar Func1
Hack5

@ Hack5 suponga que phraseuna cadena con alfabetos de la A a la Z y quiero imprimir qué alfabetos no están presentes en la cadena juntos, ¿ any()será mejor? o hay alguna forma corta de verificar?
Avishek Datta Ray

@Barefaced Desnudo en ese tipo de nivel, elija el que se vea mejor. La velocidad probablemente no importa, a menos que esté controlando las armas nucleares (en cuyo caso no debería usar Python)
Hack5

5

Esto probará si las cadenas están formadas por alguna combinación o dígitos, el signo de dólar y una coma. ¿Es eso lo que estás buscando?

importar re

s1 = 'Cadena de prueba'
s2 = '1234,12345 $'

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

if (regex.match (s1)):
   imprimir "s1 coincide"
más:
   imprimir "s1 no coincide"

if (regex.match (s2)):
   imprimir "s2 coincide"
más:
   imprimir "s2 no coincide"

No tiene que escapar del $ si está en una clase de personaje. Además, esto coincidirá 'testing $tring', lo que no creo que sea algo que el OP quiera que suceda.
NullUserException

Si recuerdo correctamente, no coincidiría 'testing $tring'si matchse usa el método, solo si searchse usa. Entonces creo que su código está bien.
dappawit

@dappa Todavía coincidirá '$string'sin embargo
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")   

de lo contrario:
print ("Carácter especial no espacial")


1
¿Podría por favor proporcionar un poco más de contexto a su respuesta?
mono de latón

comprobando el tipo de caracteres presentes en una cadena: isalnum (): Devuelve True si todos los caracteres son alfanuméricos (a a z, A a Z, 0 a 9) isalpha (): Devuelve True si todos los caracteres son solo símbolos del alfabeto (a a z, A a Z), isdigit (): Devuelve True si todos los caracteres son solo dígitos (0 a 9) islower (): Devuelve True si todos los caracteres son símbolos del alfabeto en minúscula isupper (): Devuelve True si todos los caracteres son símbolos en mayúscula istitle (): Devuelve True si la cadena está en el caso del título isspace (): Devuelve True si la cadena contiene solo espacios @LazerBass
Nagaraj
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.