jmar
23.08.2010, 11:03
Hallo,
ich wollte für mein Forum bestimmte Vorgaben für den Benutzernamen umsetzen und habe es durch die Überprüfung des Benutzernamens mit regulärem Ausdruck gelöst. Da ich wenig Ahnung von regulären Ausdrücken habe und damit ich es später auch noch durchschaue, habe ich es mir ein wenig dokumentiert. Das poste ich mal hier, falls andere vor ähnlichem Problem stehen. Vielleicht kann es ja mal jemandem nützlich sein. Und wenn jemand Fehler oder ähnliches findet, gerne her damit.
Gruss
Johannes
Nützliche Links:
http://de.wikipedia.org/wiki/Regul%C3%A4rer_Ausdruck
http://www.danielfett.de/internet-und-opensource,artikel,regulaere-ausdruecke
http://de.selfhtml.org/perl/sprache/regexpr.htm
http://www.regexlib.com/RETester.aspx
http://www.peuss.com/PHP/RegEx/erkennungEmail.php
Symbol Bedeutung
^ Zeilenanfang
$ Zeilenende bzw. Stringende
. Ein Punkt steht für ein beliebiges Zeichen.
z* Hier können beliebig viele 'z' stehen, also 0, 1 oder mehrere
z? Hier kann höchstens ein 'z' stehen, also 0 oder 1
z+ Hier kann mindestens ein 'z' stehen, also 1 oder mehrere
| trennt ODER-Blöcke
http://regexadvice.com/forums/thread/36670.aspx
Diverse dort genannte Vorgaben führen zu:
^(?!.*[-_.]{2})[a-zA-Z\d][\w.-]{1,28}[a-zA-Z\d]$
(Da hab ich mir letzten Endes meine Lösung draus gebaut! Das war der entscheidene Anstoß.)
#############################################
Ich möchte folgende Vorgaben für den Benutzernamen umsetzen.
Der Benutzername
- muss mindestens 3 und maximal X Zeichen haben (wird mit extra Option im Admin-Panel umgesetzt)
- darf nur aus vorgegebenen Buchstaben, Ziffern und bestimmten Sonderzeichen bestehen
- als Sonderzeichen sind nur erlaubt: Leerzeichen, Punkt, Bindestrich und das @-Zeichen
- darf keine Umlaute enthalten
- darf nicht mit Sonderzeichen beginnen oder enden; Ausnahme: er darf mit Punkt enden (um zum Beispiel sowas wie H.M. zuzulassen)
- darf keine aufeinanderfolgenden und/oder wiederholenden Sonderzeichen haben
Eine anscheinend recht gut funktionierende Lösung ist
^(?!.*[-.@ ]{2})[a-zA-Z0-9][-a-zA-Z0-9.@ ]+[a-zA-Z0-9.]$
(Hab ich mir zusammengebaut aus der in http://regexadvice.com/forums/thread/36670.aspx angegebenen Lösung.)
Der Part (?!.*[-.@ ]{2}) soll bewirken, dass die angegebenen Sonderzeichen nicht wiederholend auftreten können.
Etwas der Art Ausdruck2(?!Ausdruck1) ist eine "negative look-ahead assertion". Es soll besagen, dass Ausdruck1 nicht auf vorgenannten Ausdruck2 folgen darf. (Ausdruck1 wird aber selbst nicht gematcht, also nicht als Ergebnis zurückgegeben.)
Bei ^(?!.*[-.@ ]{2}) scheint es so zu laufen:
[-.@ ]{2} matcht zwei aufeinanderfolgende Zeichen aus der eckigen Klammer
.* ist ein beliebiges Zeichen beliebig oft
Zusammen heisst es also: zwei aufeinanderfolgende Zeichen an beliebiger Stelle
Das ?! macht daraus, dass diese zwei aufeinanderfolgenden Zeichen nicht auf den vorstehenden Ausdruck ^ folgen dürfen, also nicht dem Zeilenanfang folgen dürfen. D.h. sie dürfen überhaupt nicht vorkommen.
Dann kommen die drei eckigen Klammern:
[a-zA-Z0-9]
[-a-zA-Z0-9.@ ]+
[a-zA-Z0-9.]
Die erste kennzeichnet einen Buchstaben oder eine Ziffer.
Die zweite kennzeichnet einen Buchstaben, eine Ziffer oder eins der einzeln angegebenen Sonderzeichen. Das + hinter der Klammer besagt, dass 1 oder mehrere der Zeichen der vorstehenden eckigen Klammer vorkommen dürfen.
Die dritte kennzeichnet einen Buchstaben, eine Ziffer oder einen Punkt.
Und da hinter der dritten (letzten) eckigen Klammer das $ folgt, kennzeichnet die dritte eckige Klammer auch das Stringende.
Die drei eckigen Klammern zusammen verlangen also mindestens 3 Zeichen. Das erste und letzte Zeichen sind durch die jeweiligen eckigen Klammern gesondert gekennzeichnet.
###########################################
Nun fällt noch auf, dass man doch nicht alle Kombinationen der Sonderzeichen verbieten darf, um diverse sinnvolle Sachen doch zulassen zu können.
Ich drösel also das [-.@ ]{2} auf und schreibe alle Kombinationen separat hin und lasse die weg, die ich doch zulassen möchte.
L := Leerzeichen
--
..
@@
LL
alle Kombinationen:
-- -. -@ -L
.. .- .@ .L
@@ @- @. @L
LL L- L. L@
Folgende Kombinationen müsste man doch erlauben:
-L segel- und surfschule
.- T.-B.
.L T. Schwarz
L. Das .jmar.de ??? den nehme ich unten nicht
L@ Die @born ??? den hab ich unten genommen
Zum Beispiel zwei Bindestriche "verbieten"
^(?!.*--)
alle Kombinationen
^(?!.*--|.*-\.|.*-@|.*- |.*\.\.|.*\.-|.*\.@|.*\. |.*@@|.*@-|.*@\.|.*@ |.* |.* -|.* \.|.* @)
alle sinnvollen Kombinationen (mit also besagten Ausnahmen)
^(?!.*--|.*-\.|.*-@|.*\.\.|.*\.@|.*@@|.*@-|.*@\.|.*@ |.* |.* -|.* \.)
Der vollständige reguläre Ausdruck wäre also
^(?!.*--|.*-\.|.*-@|.*\.\.|.*\.@|.*@@|.*@-|.*@\.|.*@ |.* |.* -|.* \.)[a-zA-Z0-9][-a-zA-Z0-9.@ ]+[a-zA-Z0-9.]$
###########################################
Jetzt könnte man zur abschließenden Perfektionierung noch einbauen, dass Buchstaben/Ziffern maximal 4 Mal hintereinander wiederholt werden dürfen.
So dass also etwas wie annnnnnnnndi verboten würde.
( Nochmal der Hinweis, http://www.regexlib.com/RETester.aspx ist goldwert, um regexp zu testen! )
Das wird auch wieder mit "negative look-ahead assertion" gelöst, kombiniert mit Gruppierung/Referenz.
( Siehe z.B. http://perl-seiten.homepage.t-online.de/html/perl_reg.html )
\1 verweist auf das in der ersten runden Klammer gefundene.
Wiederholende Zeichen finden:
^.*([a-z])\1{3}
^(.*([a-z])\2{3})
wenn man es so schreibt, dann muss man auf \2 verweisen
Um es also auszuschließen:
^(?!.*([a-z])\2{3})
wenn man es so schreibt, dann sagt er:
parsing "^(?!.*([a-z])\2{3})" - Reference to undefined group number 2
^(?!.*([a-z])\1{3})
so funktioniert es anscheinend.
d.h. das ?! nimmt anscheinend die äußere Klammer aus dem Spiel
==========================
^(?!.*([a-zA-Z0-9üöäß])\1{4})
scheint das zu machen, was ich will
(üöäß stehen drin, obwohl ich sie bis jetzt gar nicht zulasse, aber stören ja nicht.)
alles wo die zeichen 5 Mal und öfter vorkommen moniert er (gibt "no results", weil es ja nicht vorkommen darf)
4Meba999aaabaab
da würde er matchen
4Meba99999aaabaab
da würde er "no results" machen (also das, was ich bei der Benutzernamen-Überprüfung haben möchte)
Der reguläre Ausdruck macht also:
Es darf nicht vorkommen, dass an beliebiger Stelle eins der angegebenen Zeichen gefunden wird, welches mehr als 4 Mal vorkommt.
(Das "mehr als 4" kommt daher, dass ja genau 4 Wiederholungen durch die geschweifte Klammer erforderlich sind und einmal steht es ja schon in der runden Klammer.)
Das .*([a-zA-Z0-9üöäß])\1{4} baue ich also mit | als ODER in den regulären Ausdruck mit ein (in den ?!-Part) :
Der "vollständige" alte reguläre Ausdruck war
^(?!.*--|.*-\.|.*-@|.*\.\.|.*\.@|.*@@|.*@-|.*@\.|.*@ |.* |.* -|.* \.)[a-zA-Z0-9][-a-zA-Z0-9.@ ]+[a-zA-Z0-9.]$
Der vollständige reguläre Ausdruck ist also:
^(?!.*--|.*-\.|.*-@|.*\.\.|.*\.@|.*@@|.*@-|.*@\.|.*@ |.* |.* -|.* \.|.*([a-zA-Z0-9üöäß])\1{4})[a-zA-Z0-9][-a-zA-Z0-9.@ ]+[a-zA-Z0-9.]$
Die vollständigen Vorgaben für den Benutzernamen wären also:
Der Benutzername
- muss mindestens 3 und maximal X Zeichen haben (wird mit extra Option im Admin-Panel umgesetzt)
- darf nur aus vorgegebenen Buchstaben, Ziffern und bestimmten Sonderzeichen bestehen
- hat als Sonderzeichen nur erlaubt: Leerzeichen, Punkt, Bindestrich und das @-Zeichen
- darf keine Umlaute enthalten
- darf nicht mit Sonderzeichen beginnen oder enden; Ausnahme: er darf mit Punkt enden (um zum Beispiel sowas wie H.M. zuzulassen)
- darf keine aufeinanderfolgenden und/oder wiederholenden Sonderzeichen haben
Ausnahmen: Bindestrich/Leerzeichen, Punkt/Bindestrich, Punkt/Leerzeichen und Leerzeichen/@
- darf keine ausufernden Wiederholungen von Zeichen haben (mehr als 4 Wiederholungen sind nicht möglich, also etwas wie "Daaaaaa" ist nicht möglich)
Beispiele erlaubter Benutzernamen:
Hans
Hans Muster
H. Muster
H. M.
Hans HH
Hans.HH
Hans 2
Segel- und Surfschule
h-m
Hans-Peter
surfer@hamburg
surfer @hamburg
jmar.de
und so weiter ...
Beispiele NICHT erlaubter Benutzernamen:
Hans_Muster
_Hans_
Haaaaaaans
Hans!
@Hans@
Hans@@Muster
$$$$wurgel$$$$
hm
-hm-
---hans---
und so weiter ...
ich wollte für mein Forum bestimmte Vorgaben für den Benutzernamen umsetzen und habe es durch die Überprüfung des Benutzernamens mit regulärem Ausdruck gelöst. Da ich wenig Ahnung von regulären Ausdrücken habe und damit ich es später auch noch durchschaue, habe ich es mir ein wenig dokumentiert. Das poste ich mal hier, falls andere vor ähnlichem Problem stehen. Vielleicht kann es ja mal jemandem nützlich sein. Und wenn jemand Fehler oder ähnliches findet, gerne her damit.
Gruss
Johannes
Nützliche Links:
http://de.wikipedia.org/wiki/Regul%C3%A4rer_Ausdruck
http://www.danielfett.de/internet-und-opensource,artikel,regulaere-ausdruecke
http://de.selfhtml.org/perl/sprache/regexpr.htm
http://www.regexlib.com/RETester.aspx
http://www.peuss.com/PHP/RegEx/erkennungEmail.php
Symbol Bedeutung
^ Zeilenanfang
$ Zeilenende bzw. Stringende
. Ein Punkt steht für ein beliebiges Zeichen.
z* Hier können beliebig viele 'z' stehen, also 0, 1 oder mehrere
z? Hier kann höchstens ein 'z' stehen, also 0 oder 1
z+ Hier kann mindestens ein 'z' stehen, also 1 oder mehrere
| trennt ODER-Blöcke
http://regexadvice.com/forums/thread/36670.aspx
Diverse dort genannte Vorgaben führen zu:
^(?!.*[-_.]{2})[a-zA-Z\d][\w.-]{1,28}[a-zA-Z\d]$
(Da hab ich mir letzten Endes meine Lösung draus gebaut! Das war der entscheidene Anstoß.)
#############################################
Ich möchte folgende Vorgaben für den Benutzernamen umsetzen.
Der Benutzername
- muss mindestens 3 und maximal X Zeichen haben (wird mit extra Option im Admin-Panel umgesetzt)
- darf nur aus vorgegebenen Buchstaben, Ziffern und bestimmten Sonderzeichen bestehen
- als Sonderzeichen sind nur erlaubt: Leerzeichen, Punkt, Bindestrich und das @-Zeichen
- darf keine Umlaute enthalten
- darf nicht mit Sonderzeichen beginnen oder enden; Ausnahme: er darf mit Punkt enden (um zum Beispiel sowas wie H.M. zuzulassen)
- darf keine aufeinanderfolgenden und/oder wiederholenden Sonderzeichen haben
Eine anscheinend recht gut funktionierende Lösung ist
^(?!.*[-.@ ]{2})[a-zA-Z0-9][-a-zA-Z0-9.@ ]+[a-zA-Z0-9.]$
(Hab ich mir zusammengebaut aus der in http://regexadvice.com/forums/thread/36670.aspx angegebenen Lösung.)
Der Part (?!.*[-.@ ]{2}) soll bewirken, dass die angegebenen Sonderzeichen nicht wiederholend auftreten können.
Etwas der Art Ausdruck2(?!Ausdruck1) ist eine "negative look-ahead assertion". Es soll besagen, dass Ausdruck1 nicht auf vorgenannten Ausdruck2 folgen darf. (Ausdruck1 wird aber selbst nicht gematcht, also nicht als Ergebnis zurückgegeben.)
Bei ^(?!.*[-.@ ]{2}) scheint es so zu laufen:
[-.@ ]{2} matcht zwei aufeinanderfolgende Zeichen aus der eckigen Klammer
.* ist ein beliebiges Zeichen beliebig oft
Zusammen heisst es also: zwei aufeinanderfolgende Zeichen an beliebiger Stelle
Das ?! macht daraus, dass diese zwei aufeinanderfolgenden Zeichen nicht auf den vorstehenden Ausdruck ^ folgen dürfen, also nicht dem Zeilenanfang folgen dürfen. D.h. sie dürfen überhaupt nicht vorkommen.
Dann kommen die drei eckigen Klammern:
[a-zA-Z0-9]
[-a-zA-Z0-9.@ ]+
[a-zA-Z0-9.]
Die erste kennzeichnet einen Buchstaben oder eine Ziffer.
Die zweite kennzeichnet einen Buchstaben, eine Ziffer oder eins der einzeln angegebenen Sonderzeichen. Das + hinter der Klammer besagt, dass 1 oder mehrere der Zeichen der vorstehenden eckigen Klammer vorkommen dürfen.
Die dritte kennzeichnet einen Buchstaben, eine Ziffer oder einen Punkt.
Und da hinter der dritten (letzten) eckigen Klammer das $ folgt, kennzeichnet die dritte eckige Klammer auch das Stringende.
Die drei eckigen Klammern zusammen verlangen also mindestens 3 Zeichen. Das erste und letzte Zeichen sind durch die jeweiligen eckigen Klammern gesondert gekennzeichnet.
###########################################
Nun fällt noch auf, dass man doch nicht alle Kombinationen der Sonderzeichen verbieten darf, um diverse sinnvolle Sachen doch zulassen zu können.
Ich drösel also das [-.@ ]{2} auf und schreibe alle Kombinationen separat hin und lasse die weg, die ich doch zulassen möchte.
L := Leerzeichen
--
..
@@
LL
alle Kombinationen:
-- -. -@ -L
.. .- .@ .L
@@ @- @. @L
LL L- L. L@
Folgende Kombinationen müsste man doch erlauben:
-L segel- und surfschule
.- T.-B.
.L T. Schwarz
L. Das .jmar.de ??? den nehme ich unten nicht
L@ Die @born ??? den hab ich unten genommen
Zum Beispiel zwei Bindestriche "verbieten"
^(?!.*--)
alle Kombinationen
^(?!.*--|.*-\.|.*-@|.*- |.*\.\.|.*\.-|.*\.@|.*\. |.*@@|.*@-|.*@\.|.*@ |.* |.* -|.* \.|.* @)
alle sinnvollen Kombinationen (mit also besagten Ausnahmen)
^(?!.*--|.*-\.|.*-@|.*\.\.|.*\.@|.*@@|.*@-|.*@\.|.*@ |.* |.* -|.* \.)
Der vollständige reguläre Ausdruck wäre also
^(?!.*--|.*-\.|.*-@|.*\.\.|.*\.@|.*@@|.*@-|.*@\.|.*@ |.* |.* -|.* \.)[a-zA-Z0-9][-a-zA-Z0-9.@ ]+[a-zA-Z0-9.]$
###########################################
Jetzt könnte man zur abschließenden Perfektionierung noch einbauen, dass Buchstaben/Ziffern maximal 4 Mal hintereinander wiederholt werden dürfen.
So dass also etwas wie annnnnnnnndi verboten würde.
( Nochmal der Hinweis, http://www.regexlib.com/RETester.aspx ist goldwert, um regexp zu testen! )
Das wird auch wieder mit "negative look-ahead assertion" gelöst, kombiniert mit Gruppierung/Referenz.
( Siehe z.B. http://perl-seiten.homepage.t-online.de/html/perl_reg.html )
\1 verweist auf das in der ersten runden Klammer gefundene.
Wiederholende Zeichen finden:
^.*([a-z])\1{3}
^(.*([a-z])\2{3})
wenn man es so schreibt, dann muss man auf \2 verweisen
Um es also auszuschließen:
^(?!.*([a-z])\2{3})
wenn man es so schreibt, dann sagt er:
parsing "^(?!.*([a-z])\2{3})" - Reference to undefined group number 2
^(?!.*([a-z])\1{3})
so funktioniert es anscheinend.
d.h. das ?! nimmt anscheinend die äußere Klammer aus dem Spiel
==========================
^(?!.*([a-zA-Z0-9üöäß])\1{4})
scheint das zu machen, was ich will
(üöäß stehen drin, obwohl ich sie bis jetzt gar nicht zulasse, aber stören ja nicht.)
alles wo die zeichen 5 Mal und öfter vorkommen moniert er (gibt "no results", weil es ja nicht vorkommen darf)
4Meba999aaabaab
da würde er matchen
4Meba99999aaabaab
da würde er "no results" machen (also das, was ich bei der Benutzernamen-Überprüfung haben möchte)
Der reguläre Ausdruck macht also:
Es darf nicht vorkommen, dass an beliebiger Stelle eins der angegebenen Zeichen gefunden wird, welches mehr als 4 Mal vorkommt.
(Das "mehr als 4" kommt daher, dass ja genau 4 Wiederholungen durch die geschweifte Klammer erforderlich sind und einmal steht es ja schon in der runden Klammer.)
Das .*([a-zA-Z0-9üöäß])\1{4} baue ich also mit | als ODER in den regulären Ausdruck mit ein (in den ?!-Part) :
Der "vollständige" alte reguläre Ausdruck war
^(?!.*--|.*-\.|.*-@|.*\.\.|.*\.@|.*@@|.*@-|.*@\.|.*@ |.* |.* -|.* \.)[a-zA-Z0-9][-a-zA-Z0-9.@ ]+[a-zA-Z0-9.]$
Der vollständige reguläre Ausdruck ist also:
^(?!.*--|.*-\.|.*-@|.*\.\.|.*\.@|.*@@|.*@-|.*@\.|.*@ |.* |.* -|.* \.|.*([a-zA-Z0-9üöäß])\1{4})[a-zA-Z0-9][-a-zA-Z0-9.@ ]+[a-zA-Z0-9.]$
Die vollständigen Vorgaben für den Benutzernamen wären also:
Der Benutzername
- muss mindestens 3 und maximal X Zeichen haben (wird mit extra Option im Admin-Panel umgesetzt)
- darf nur aus vorgegebenen Buchstaben, Ziffern und bestimmten Sonderzeichen bestehen
- hat als Sonderzeichen nur erlaubt: Leerzeichen, Punkt, Bindestrich und das @-Zeichen
- darf keine Umlaute enthalten
- darf nicht mit Sonderzeichen beginnen oder enden; Ausnahme: er darf mit Punkt enden (um zum Beispiel sowas wie H.M. zuzulassen)
- darf keine aufeinanderfolgenden und/oder wiederholenden Sonderzeichen haben
Ausnahmen: Bindestrich/Leerzeichen, Punkt/Bindestrich, Punkt/Leerzeichen und Leerzeichen/@
- darf keine ausufernden Wiederholungen von Zeichen haben (mehr als 4 Wiederholungen sind nicht möglich, also etwas wie "Daaaaaa" ist nicht möglich)
Beispiele erlaubter Benutzernamen:
Hans
Hans Muster
H. Muster
H. M.
Hans HH
Hans.HH
Hans 2
Segel- und Surfschule
h-m
Hans-Peter
surfer@hamburg
surfer @hamburg
jmar.de
und so weiter ...
Beispiele NICHT erlaubter Benutzernamen:
Hans_Muster
_Hans_
Haaaaaaans
Hans!
@Hans@
Hans@@Muster
$$$$wurgel$$$$
hm
-hm-
---hans---
und so weiter ...