Wie überprüfe ich eine Zeichenfolge auf bestimmte Zeichen? [geschlossen]


182

Wie kann ich mit Python 2 überprüfen, ob eine Zeichenfolge mehrere bestimmte Zeichen enthält?

Beispiel: Geben Sie die folgende Zeichenfolge ein:

Die Kriminellen haben 1.000.000 Dollar an Juwelen gestohlen.

Wie erkenne ich, ob Dollarzeichen ("$"), Kommas (",") und Zahlen vorhanden sind?


1
Bedeutet das, dass jedes Zeichen eines davon sein soll, oder reicht es aus, dass eines (oder alle) dieser Zeichen in der Zeichenfolge vorhanden ist? Müssen sie in einer bestimmten Reihenfolge (z. B. 2,00 USD) sein, damit sie gültig sind?
NullUserException

2
Genau wie bei einem anderen Ansatz, not set(p).isdisjoint(set("0123456789$,"))wo pist die zu testende Zeichenfolge.
Kevin

Antworten:


265

Angenommen, Ihre Zeichenfolge lautet 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

Und so weiter für andere Charaktere.

... oder

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

... oder

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

[Bearbeiten: '$' in sAntworten hinzugefügt ]


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

Gibt es einen bestimmten Grund, warum der Wert für nicht gefunden -1 und nicht 0 beibehalten wurde?
Akki

2
@akki nicht gefunden ist -1, da 0 der Index des ersten Zeichens in einer Zeichenfolge ist. Somit ist "abc" .find ('a') = 0. Es wäre mehrdeutig, wenn 0 auch der nicht gefundene Wert wäre.
Lemiant

1
Ich mag diese letzte Version mit any(). Gibt es eine Möglichkeit, auf das gefundene Zeichen cin einem pythonischen Stil zu verweisen (es scheint nur innerhalb von zu liegen any()), oder müsste ich die Suche nach mehreren Zeichen expliziter gestalten?
Jens

3
Das zweite Beispiel ist fehlerhaft: Der reguläre Ausdruck muss in Klammern stehen, r'[\d\$,]'damit er mit einem dieser Zeichen übereinstimmt, und else:am Ende fehlt der Doppelpunkt.
Bjnord

23

Benutzer Jochen Ritzel sagte dies in einem Kommentar zu einer Antwort auf diese Frage von Benutzer dappawit. Es sollte funktionieren:

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

'1', '2' usw. sollten durch die gesuchten Zeichen ersetzt werden.

Auf dieser Seite in der Python 2.7-Dokumentation finden Sie einige Informationen zu Zeichenfolgen, einschließlich zur Verwendung des inOperators für Teilstringtests.

Update: Dies macht den gleichen Job wie mein obiger Vorschlag mit weniger Wiederholungen:

# 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 Dies ist kompakter als mehrere .find () und in Ordnung, solange die Anzahl der gesuchten Zeichen gering ist. Benötigt aber keine Klammern.
Sean

1
@ Sean Über die Klammern: Ich weiß, aber es ist einfacher für mich, sie immer zu verwenden, als mich immer an die Rangfolge zu erinnern :-).
Abbafei

11

Schneller Vergleich der Timings als Antwort auf den Beitrag von 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))

Ausgabe:

Func1 Time: 0.0737484362111
Func2 Time: 0.0125144964371

Der Code ist also mit jedem kompakter, mit der Bedingung jedoch schneller.


EDIT: TL; DR - Bei langen Saiten ist if-then immer noch viel schneller als alle anderen!

Ich habe beschlossen, das Timing für eine lange zufällige Zeichenfolge anhand einiger der in den Kommentaren angesprochenen gültigen Punkte zu vergleichen:

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

Ausgabe:

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

Wenn-dann ist fast eine Größenordnung schneller als jede andere!


1
genau das, was ich wissen wollte :-)
Lars

1
Kann jemand erklären, warum die Bedingung so viel schneller ist als die Verwendung?
Josh

@ Josh wahrscheinlich ist es, weil es einfacher ist. Func1 verwendet das Explosionslistenverständnis, sodass es für einfache Dinge automatisch komplexer wird. Aber für 1000 Zeichen kann es durchaus schneller sein, Func1
Hack5

@ Hack5 Angenommen, phraseeine Zeichenfolge mit Alphabeten von A bis Z und ich möchte drucken, welche Alphabete nicht in einer Zeichenfolge enthalten sind. Wird die Verwendung any()besser sein? oder gibt es eine kurze Möglichkeit zu überprüfen?
Avishek Datta Ray

@Barefaced Bare auf dieser Ebene, wählen Sie, was besser aussieht. Die Geschwindigkeit spielt wahrscheinlich keine Rolle, es sei denn, Sie steuern Atomwaffen (in diesem Fall sollten Sie Python nicht verwenden)
Hack5

5

Dadurch wird geprüft, ob Zeichenfolgen aus einer Kombination oder Ziffern, dem Dollarzeichen und einem Komma bestehen. Ist es das, wonach du suchst?

import re

s1 = 'Testzeichenfolge'
s2 = '1234,12345 $'

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

if (regex.match (s1)):
   print "s1 stimmt überein"
sonst:
   print "s1 stimmte nicht überein"

if (regex.match (s2)):
   print "s2 stimmt überein"
sonst:
   print "s2 stimmte nicht überein"

Sie müssen dem $ nicht entkommen, wenn es sich um eine Charakterklasse handelt. Auch das wird passen 'testing $tring', was ich nicht denke, dass das OP passieren will.
NullUserException

Wenn ich mich richtig erinnere, würde es nicht übereinstimmen 'testing $tring', wenn die matchMethode verwendet wird, nur wenn sie searchverwendet wird. Also ich denke sein Code ist in Ordnung.
Dappawit

@dappa Es wird noch passen , '$string'obwohl
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")   

sonst:
print ("Sonderzeichen ohne Leerzeichen")


1
Könnten Sie bitte Ihrer Antwort etwas mehr Kontext geben?
Messingaffe

Überprüfen des in einer Zeichenfolge vorhandenen Zeichentyps: isalnum (): Gibt True zurück, wenn alle Zeichen alphanumerisch sind (a bis z, A bis Z, 0 bis 9). isalpha (): Gibt True zurück, wenn alle Zeichen nur Alphabetsymbole sind (a bis z, A bis Z), isdigit (): Gibt True zurück, wenn alle Zeichen nur Ziffern sind (0 bis 9). Islower (): Gibt True zurück, wenn alle Zeichen Kleinbuchstaben sind. Isupper (): Gibt True zurück, wenn alle Zeichen Großbuchstaben sind (istitle): Gibt True zurück , wenn der String in Titel Fall isspace (): Gibt True zurück , wenn der String nur Leerzeichen @LazerBass enthält
Nagaraj
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.