string auf sonerzeichen prüfen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mop
User
Beiträge: 6
Registriert: Mittwoch 26. September 2007, 16:10

Mittwoch 26. September 2007, 16:15

hallo,

ich muß einen string auf sonderzeichen überprüfen, d.h., es dürfen nur buchstaben von a-z und zahlen von 0-9 enthalten sein!

vermutlich lässt sich das m.H. von regulären ausdrücken lösen? leider steig ich da gar nicht dahinter. bin für hilfe dankbar.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Mittwoch 26. September 2007, 16:33

Warum so kompliziert?

Code: Alles auswählen

>>> "abcd1234".isalnum()
True
>>> "sdf)(_(^**&%23".isalnum()
False
:lol:
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
mop
User
Beiträge: 6
Registriert: Mittwoch 26. September 2007, 16:10

Mittwoch 26. September 2007, 16:55

wunderbar. ich danke dir
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Mittwoch 26. September 2007, 19:14

Aber Vorsicht:

Code: Alles auswählen

>>> "Ätschbätsch".isalnum()
True
Zumindest, wenn die deutsche Locale eingeschaltet ist.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Mittwoch 26. September 2007, 19:15

... was sie standardmäßig nicht ist, nur wenn du `locale.setlocale()` aufrufst.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Mittwoch 26. September 2007, 19:58

... oder unter Windows arbeitest. Da habe ich es gerade getestet, ohne einen Aufruf von setlocale
BlackJack

Mittwoch 26. September 2007, 20:24

Wo denn da genau? In einer IDE die vielleicht `setlocale()` aufgerufen hat?
poker
User
Beiträge: 146
Registriert: Donnerstag 20. September 2007, 21:44

Donnerstag 27. September 2007, 11:59

BlackJack hat geschrieben:Wo denn da genau? In einer IDE die vielleicht `setlocale()` aufgerufen hat?
IDLE?

BTW: Unter IDLE kann ich das auch bestätigen. IDLE liest wohl aus welche Systemsprache eingestellt ist, stellts so ein. -- ipython macht das übrigens nicht.

@mop
IMO ist diese Verhalten aber Richtig. Wenn du wirklich ausschließen willst das nicht andere Zeichen außer Groß- und Kleinbuchstaben plus zahlen vorkommen, tut es diese Funktion:

Code: Alles auswählen

import re
_isalnum_re = re.compile(r'[^a-zA-Z0-9]')
def isalnum_re_extern(s):
    if not s: return False # Leerstring
    return _isalnum_re.search(s) is None
@
Benchmark:

Code: Alles auswählen

from timeit import Timer
import re
import string as str_

def isalnum_re(s):
    if not s: return False # Leerstring
    return re.compile(r'[^a-zA-Z0-9]').search(s) is None

_isalnum_re = re.compile(r'[^a-zA-Z0-9]')
def isalnum_re_extern(s):
    if not s: return False # Leerstring
    return _isalnum_re.search(s) is None

asci_digits = str_.ascii_letters + str_.digits
def isalnum_iterative(s):
    if not s: return False # Leerstring
    for i in s:
        if i not in asci_digits:
            return False
    return True

def isalnum(s):
    return s.isalnum()

testdatas = [
    ("Kurzer Text - Leerzeichen und Buchstaben",
     "Lorem ipsum reque debitis philosophia"),
    ("Kurzer Text - Leerzeichen, Buchstaben und Sonderzeichen",
     "Lörem ipsüm reqüe debitis %$/§"~philösöphia"),
    ("Kurzer Text - Sonderzeichen",
     "äö%§/)=!$82§&Ö$/()§"!EFSD@"),
    ("Alle druckbaren Zeichen", str_.printable),
    ("ascii", str_.ascii_letters),
    ("digits", str_.digits),
    ("digits + ascii", str_.digits + str_.ascii_letters),
    ("Sehr langer Text!!", """"Lorem ipsum reque debitis philosophia qui ea, ex usu munerehonestatis.
Ei ceter o scaevola quo, corrumpit referrentur mei ex. Idvide duis recusabo sed,
id sea m
inimum atomorum. In idque dolore quo,nobis veritus delectus qui in.  Duo porro a
tomorum theophrastus ne,mei quot timeam facilis ea. His ei primis dictas, at vis
 possepericulis vulputate. Cum vero detraxit maluisset ad, per omnes minimumlege
ndos an. Ex vix adhuc ubique virtute, wisi repudiare vix no.Animal mentitum id i
us. Id assum equidem neglegentur pro, muciusgubergren at ius. No sea choro volup""" * 50)]
testdatas.append(("Binär", testdatas[-1][1].encode("base64").encode("zip")))
testdatas.append(("*sehr* viel binär gefolgt von Text!!",
                  testdatas[-1][1] * 25 + testdatas[-2][1] * 25))

loops = 1000000
td = None
for name, td in testdatas:
    print "%s:" % name
    t = Timer("isalnum_re(td)",
              "from __main__ import isalnum_re, td").timeit(loops)
    print "\tisalnum_re - %.3fsec" % t

    t = Timer("isalnum_re_extern(td)",
              "from __main__ import isalnum_re_extern, td").timeit(loops)
    print "\tisalnum_re_extern - %.3fsec" % t

    t = Timer("isalnum_iterative(td)",
              "from __main__ import isalnum_iterative, td").timeit(loops)
    print "\tisalnum_iterative - %.3fsec" % t

    t = Timer("isalnum(td)",
              "from __main__ import isalnum, td").timeit(loops)
    print "\tisalnum - %.3fsec" % t
    print

Tjoa, `isalnum` ist immer schneller (BTW: ich hab die str methode in eine funktion gekapselt, damit dort der gleiche Overhead (=Funktionsaufruf) entsteht wie beim rest).

Je nach Daten ist mal `isalnum_iterative`schneller oder `isalnum_re_extern`. Nett ist vor allem zu beobachten das die iterative Methode sehr langsam ist, wenn der vorhandene Text nur aus Buchstaben oder oder Zahlen besteht; dort kann die re engine Punkten.
Hervorzuheben ist auch, das es viel bringt das pattern für SRE außerhalb zu erstellen.

Aber letztendlich sind die Ergebnisse Syntetisch und auf die Realität nicht übertragbar :roll:

Code: Alles auswählen

Kurzer Text - Leerzeichen und Buchstaben:
	isalnum_re - 4.554sec
	isalnum_re_extern - 2.351sec
	isalnum_iterative - 2.099sec
	isalnum - 0.736sec

Kurzer Text - Leerzeichen, Buchstaben und Sonderzeichen:
	isalnum_re - 4.414sec
	isalnum_re_extern - 2.092sec
	isalnum_iterative - 1.177sec
	isalnum - 0.606sec

Kurzer Text - Sonderzeichen:
	isalnum_re - 4.308sec
	isalnum_re_extern - 1.867sec
	isalnum_iterative - 0.903sec
	isalnum - 0.581sec

Alle druckbaren Zeichen:
	isalnum_re - 6.436sec
	isalnum_re_extern - 4.179sec
	isalnum_iterative - 16.832sec
	isalnum - 2.243sec

ascii:
	isalnum_re - 5.333sec
	isalnum_re_extern - 2.925sec
	isalnum_iterative - 14.259sec
	isalnum - 2.186sec

digits:
	isalnum_re - 3.951sec
	isalnum_re_extern - 1.550sec
	isalnum_iterative - 4.296sec
	isalnum - 0.857sec

digits + ascii:
	isalnum_re - 5.637sec
	isalnum_re_extern - 3.242sec
	isalnum_iterative - 17.265sec
	isalnum - 2.229sec

Sehr langer Text!!:
	isalnum_re - 4.311sec
	isalnum_re_extern - 1.877sec
	isalnum_iterative - 0.900sec
	isalnum - 0.584sec

Binär:
	isalnum_re - 4.404sec
	isalnum_re_extern - 2.040sec
	isalnum_iterative - 1.160sec
	isalnum - 0.603sec

*sehr* viel binär gefolgt von Text!!:
	isalnum_re - 4.420sec
	isalnum_re_extern - 2.062sec
	isalnum_iterative - 1.158sec
	isalnum - 0.611sec
Antworten