Seite 1 von 1

Regex: Genaue Anzahl matchen

Verfasst: Montag 20. August 2007, 16:08
von mkesper
Hallo,

Laut dem Regular Expression Howto sollte Folgendes ein Muster für einen String mit 15 alphanumerischen Zeichen sein, es matcht aber nicht:

Code: Alles auswählen

In [20]: pattern = re.compile(r'\w{15,15}', re.IGNORECASE)

In [21]: print pattern.match('kol06tsehv-id01')
None
Mit

Code: Alles auswählen

pattern = re.compile(r'\w*', re.IGNORECASE)
matcht es, ich würde aber gerne jeden Char auf die Bedingung prüfen.

Verfasst: Montag 20. August 2007, 16:33
von EyDu
Das es keinen Match gibt liegt einfach daran, dass "-" kein alpha-numerisches Zeichen ist.

Und das "\w*" gibt auch keinen Match fuer den gesamten String, sondern nur "kol06tsehv".

Schau dir dir Dokumentation bezüglich REs noch mal an, und im besonderen das "^" und das "$".

Was du suchst ist wahrscheinlich das folgende:

Code: Alles auswählen

pattern = re.compile(r'^[\w-]{15,15}$', re.IGNORECASE)
Wobei man sich unter Umständen das ^ und $ sparen kann.

Verfasst: Montag 20. August 2007, 16:34
von BlackJack
Das '-' ist weder Buchstabe noch Ziffer. Genau da hört Dein zweiter regulärer Ausdruck auf. Wenn das '-' mit drin sein soll, musst Du es auch im Ausdruck erwähnen.

Code: Alles auswählen

In [22]: pattern = re.compile(r'\w*', re.IGNORECASE)

In [23]: a = pattern.match('kol06tsehv-id01')

In [24]: a.group()
Out[24]: 'kol06tsehv'

In [25]: pattern = re.compile(r'[-\w]{15}', re.IGNORECASE)

In [26]: a = pattern.match('kol06tsehv-id01')

In [27]: a.group()
Out[27]: 'kol06tsehv-id01'

Verfasst: Dienstag 21. August 2007, 08:22
von mkesper
EyDu hat geschrieben:Das es keinen Match gibt liegt einfach daran, dass "-" kein alpha-numerisches Zeichen ist.
Ist natürlich einleuchtend, ich hatte das in der Doku falsch gelesen.

Code: Alles auswählen

pattern = re.compile(r'^[\w-]{15,15}$', re.IGNORECASE)
ist genau das, was ich suchte, ansonsten müßte ich nochmal auf die Länge des Matches prüfen.
Danke!

Verfasst: Dienstag 21. August 2007, 10:30
von Leonidas
Du brauchst nur einmal die 15 in den geschweiften Klammern.
re Dokumentation hat geschrieben:{m}
Specifies that exactly m copies of the previous RE should be matched; fewer matches cause the entire RE not to match. For example, a{6} will match exactly six "a" characters, but not five.

Verfasst: Dienstag 21. August 2007, 11:12
von EyDu
mkallas hat geschrieben:ist genau das, was ich suchte, ansonsten müßte ich nochmal auf die Länge des Matches prüfen.
Nur noch so eine Idee von mir: Soll der "-" eine Trennung des Strings darstellen? Gegen den genannten Ausdruck zu testen wäre dann wohl kaum sinvoll, da auch "---------------" gematcht werden würde. In so einem Fall würde ich folgendes empfehlen:

Code: Alles auswählen

x = 'kol06tsehv-id01'
pattern = re.compile(r'^\w+-\w+$', re.IGNORECASE)
if len(x)==15 and pattern.match(x):
    print 'OK'
else:
    print 'HMPF'

Verfasst: Dienstag 21. August 2007, 13:52
von Leonidas
Vielleicht steht der Bindestrich aber auch immer an der gleichen stelle, dann kann man das noch etwas vereinfachen:

Code: Alles auswählen

re.compile(r'^[\w]{10}-[\w]{4}$', re.I)
Dann spart man sich die Längenprüfung.

Verfasst: Mittwoch 22. August 2007, 08:09
von mkesper
EyDu hat geschrieben:Nur noch so eine Idee von mir: Soll der "-" eine Trennung des Strings darstellen? Gegen den genannten Ausdruck zu testen wäre dann wohl kaum sinvoll, da auch "---------------" gematcht werden würde.
Also ist es doch noch ein wenig komplizierter:
'-' * 15 ist natürlich unzulässig
'-' an erster und letzter Stelle sollte auch nicht vorkommen, ansonsten gibt es aber leider noch Relikte, die mehr als einen Bindestrich aufweisen.
eine passende re müsste dann sein:

Code: Alles auswählen

pattern = re.compile(r'^(\w+-*\w+)+$')
Den Ignorecase kann man hier weglassen, da \w sowieso auf a-z und A-Z geht, habe ich gerade gemerkt. Dafür muß dann wieder die Länge des Strings begutachtet werden.

Verfasst: Mittwoch 22. August 2007, 08:42
von Leonidas
Wie wärs dann mit

Code: Alles auswählen

pattern = re.compile(r'^\w[\w-]{13}\w$')
Das Stellt sicher dass es nicht mit einem Bindestrich beginnt oder endet und dass die Länge 15 ist. Man kann zwar immer noch 13 Bindestriche einfügen, aber irgendwann ist mit dem Mustererkennen per Regular Expression schluss und man muss den String normal validieren.