PHP string mit regex prüfen

servus,

kurz gefasst: ich brauche eine funktion, die prüft, ob in einem übergebenen string mindestens eine zahl und mindestens ein buchstabe enthalten sind. entsprechend boolean als rückgabe.

also in etwa so:

function validate($string) { return preg_match( 'pruefung ob mind eine zahl enthalten ist', $string ) and preg_match( 'pruefung ob mind ein buchstabe enthalten ist', $string ) }

außerdem:

folgende funktion mit ereg habe ich bisher verwendet, allerdings habe ich vor kurzen gelesen, dass die seit 5.3.0 veraltet ist (prüft eine e-mail adresse):

das problem ist, dass ich auch gelesen habe, dass die syntax anders ist als bei preg_match, stimmt das? wenn ja, kann mir einer von euch (nich haun) freaks das “übersetzen”? :slight_smile:

was ich noch besser fänd wär wenn jemand, falls er so lieb is und das für mich hier schnell posten möchte, kurz erklärt was wobei passiert, das sind für mich nämlich nach wie vor hyroglyphen (<- rächtschreipunk^^)…

gruß
emil

Dann schreib dir eine :stuck_out_tongue:

Zwei Zeichenklassen, eine für Buchstaben, eine für Zahlen - das sollte mit Grundkenntnissen machbar sein.
Und dann hängst du die entweder als Alternativen verknüpft zwei mal hintereinander (damit du erst Buchstabe, dann Ziffer und umgekehrt abdeckst), oder du testest auf beide Zeichenklassen mit zwei einzelnen preg_match-Aufrufen, und verknüpfst deren Ergebnis.

Das sollte man sowieso nicht selber machen - weil ein Ausdruck, der wirklich korrekt auf die Einhaltung der (durchaus komplexen) Syntax einer E-Mail-Adresse prüft, auch entsprechend komplex wird - das geht idR. über ein Dutzend Zeilen oder in der Größenordnung.

Stattdessen: PHPs filter anschauen - da gibt’s auch einen für E-Mail-Adressen.

[quote]Dann schreib dir eine :stuck_out_tongue:
[/quote]
Wenn er es könnte würde er wahrscheinlich nicht fragen. :p

Hallo emil,

ich bin kein Experte mit Regex aber versuch es mal damit:

<span class="syntaxdefault">function validate</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$string</span><span class="syntaxkeyword">)<br />{<br /></span><span class="syntaxdefault">    $pattern </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxstring">"#[a-zA-Z]{1,}[0-9]{1,}#"</span><span class="syntaxkeyword">;<br /><br /></span><span class="syntaxdefault">    return preg_match</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$pattern</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> $string</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">==</span><span class="syntaxdefault"> 1</span><span class="syntaxkeyword">;<br />}<br /></span><span class="syntaxdefault"> </span>

Was hast Du genau vor ? Evt. geht es auch ohne die Reg. Ausdrücke.

MfG

Sowat würd auch gehen:
.?(?:[\d].?[a-zA-Z]|[a-zA-Z].?[\d]).<span class="syntaxdefault">preg_match</span><span class="syntaxkeyword">(</span><span class="syntaxstring">'/.*?(?:[\d].*?[a-zA-Z]|[a-zA-Z].*?[\d]).*/'</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">$test</span><span class="syntaxkeyword">);&nbsp;</span><span class="syntaxdefault"></span>
Allerdings bin ich net sicher ob der RegEx nicht noch iwie simpler geht als das :ps: [size=85](zumindest könnte man das „irgendwas“ am Anfang und Ende weglassen)[/size]

PS: Nen RegEx kann man übrigens immer recht schnell mit ner Webseite prüfen. z.B.
regexpal.com/

Edit: stimmt ja… PHP will den Anfang und das Ende eines RegEx haben xD
Nachtrag: wenn man das „irgendwas“ am Anfang und Ende weglassen will, dann tuts auch das hier:<span class="syntaxdefault">preg_match</span><span class="syntaxkeyword">(</span><span class="syntaxstring">'/[\d].*?[a-zA-Z]|[a-zA-Z].*?[\d]/'</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">$test</span><span class="syntaxkeyword">);&nbsp;</span><span class="syntaxdefault"></span>

function containsCharAndNumber($string)
{
	return strpbrk($string, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") !== false &&
		strpbrk($string, "0123456789") !== false;
}

Also kein Grund hier einen Smiliezirkus zu benutzen :wink:

EDIT:

Hier nur mal so der RegExp den PHP zum Validieren von E-Mails in den filter_*-Funktionen benutzt:

¿WTF?
Geht das net einfacher :smiley:? Nen „\w±.“ für die Mail und „\w-.“ für die Domain tuts doch auch oder net? Ok es gibt Sonderzeichen in Domains… die müsste man theoretisch auch beachten… aber da könnte man vorm RegEx die Domain Punycoden und gut is…
Namen können nur Buchstaben [size=85](inkl. Unterstrich)[/size], + - und Punkt beinhalten. [size=85](vielleicht noch 1-2 andere Zeichen, weiß ich jetzt nicht, jedenfalls keine Sonderzeichen denn sonst würden ja auch Umlaute gehen und bei mir gingen keine.)[/size]

Edit: ok… es ist doch verdammt viel erlaubt^^ Komisch nur das die meisten Anbieter nur nen Bruchteil davon erlauben… [size=85](ok es macht E-Mails vernünftige da einfacher zu merken / aufzuschreiben etc. Wer will schon ne Mail mit allen möglichen Sonderzeichen von jemandem Diktiert bekommen :ps:)[/size]

Gott, nun mach es doch einfach wie chris schon gesagt hat.
pattern eins mit \d+, zweites mit \w+

Die Summe der beiden Ergebniss muss also > 1 sein.

servus leute,

erstmal danke für die vielen antworten.

= 1 :wink:

naja bei ner email sind schon ne menge dinge zu beachten, etwa dass die domain mindestens 2 zeichen haben muss, aber die tld nicht länger als 4 zeichen sein darf, blablabla, kommt schon was zam.
ich denke ich werde das machen wie chris schon gesagt hat, von den filtern wusste ich bisher nichts, wär ja blödsinn das rat neu zu erfinden :wink:

der sinn dahinter ist, zu prüfen, ob ein passwort, das ein user festlegen kann, auch eine gewisse komplexität hat.

->[quote=„Starhunter“]Wenn er es könnte würde er wahrscheinlich nicht fragen. :p [/quote]

mit regex hatte ich bisher wirklich nie zu tun, für die minimalen dinge für die ich es bisher verwendet habe, hab ichs mir zusammenkopieren können, bzw bei htaccess rewrite-conds wende ich mich immer vertrauensvoll ans forum :wink:

also, nochmal danke an alle, ich denk aus euren antworten werd ich mir ein paar lösungen ansehen und die eleganteste übernehmen. :wink2:

Also erstmal zum Thema der Passwortkomplexität.

Ich habe das ganze mal hinsichtlich der Geschwindigkeit getestet, mit folgendem Ergebnis:

[code]Starte Überprüfung mit containsCharAndNumber() und 20000 Durchgängen (Teststring = ‘1234ABCxyz’).
Überprüfung abgeschlossen: 65.401077270508ms

Starte Überprüfung mit containsCharAndNumber() und 20000 Durchgängen (Teststring = ‘abcdefGHIJ’).
Überprüfung abgeschlossen: 64.286947250366ms

Starte Überprüfung mit preg_match() und 20000 Durchgängen (Teststring = ‘1234ABCxyz’).
Überprüfung abgeschlossen: 83.823919296265ms

Starte Überprüfung mit preg_match() und 20000 Durchgängen (Teststring = ‘abcdefGHIJ’).
Überprüfung abgeschlossen: 108.402967453ms[/code]
(XAMPP 1.7.4; WinVista HP SP2 x64; Intel Core 2 Duo E7400 @ 2.80GHz; 4.0GB Dual-Kanal DDR2 @ 332MHz (5-5-5-15))

Daran lässt sich erkennen, dass strpbrk zumindest bei kurzen (aber auf Grund des Aufwands bei Regulären Ausdrücken wahrscheinlich auch bei längeren) Zeichenketten schneller arbeitet als die RegExp-Variante. Wer das bei sich selbst ausprobieren möchte, kann mir eine PN schreiben, dann bekommt derjenige den Quelltext.

So, jetzt zur E-Mail-Validierung. Das wird eindeutig überbewertet. Selbst die exakte Überprüfung nach RFC ermöglicht es dem Nutzer immernoch z.B. fake@example.com anzugeben. Meiner Meinung nach reicht es vollkommen aus zu prüfen, ob ein @-Zeichen vorkommt und das gleiche nochmal für den Punkt im Domainteil. Der RegExp /.+@.+.[a-z]{2,6}/i sollte dafür ausreichen. Sinn ist hier meiner Meinung nach eher Tippfehler abzufangen als valide E-Mail-Adressen zu erzwingen.

[quote=“zvn”]Daran lässt sich erkennen, dass strpbrk [] schneller arbeitet [] Wer das bei sich selbst ausprobieren möchte, kann mir eine PN schreiben, dann bekommt derjenige den Quelltext.[/quote]Selbst probieren ist nicht nötig :wink: Das die PHP eigene Funktion, die genau das hier gewünschte tut, schneller arbeitet als nen RegEx, ist eigl. zu erwarten^^ Sonst wäre PHP echt schlecht geschrieben xD
Interessant wäre höchstens dein RegEx, denke aber du hast schon den “schnellsten” genommen. So oder so, das Ergebnis sollte immer gleich bleiben. [size=85](ich wusste für meinen Teil nicht das es so eine PHP Funktion gibt :smiley: Der Name is ja auch net gerade einfach)[/size]

[quote=“zvn”]So, jetzt zur E-Mail-Validierung. Das wird eindeutig überbewertet. Selbst die exakte Überprüfung nach RFC ermöglicht es dem Nutzer immernoch z.B. fake@example.com anzugeben. Meine Meinung nach reicht es vollkommen aus zu prüfen, ob ein @-Zeichen vorkommt und das gleiche nochmal für den Punkt im Domainteil. Der RegExp /.+@.+.[a-z]{2,6}/i sollte dafür ausreichen. Sinn ist hier meiner Meinung nach eher Tippfehler abzufangen als valide E-Mail-Adressen zu erzwingen.[/quote]korrekt! Wobei nen komplizierterer RegEx auch nicht so ins Gewicht fallen sollte…
Wenn ich übrigens mal auf ne Seite stoße die ne E-Mail fürn Download verlangt, dann geb ich immer “admin@DomainDerSeite.tld” an xD Wobei nicht immer “admin/webmaster/postmaster”… jenachdem auch “GoDie” “Ignore” o.ä. [size=85](natürlich Kreuze ich nicht an das Newsletter o.ä. gewollt seien, sollen sich ja net selbst zumüllen, zumindest nicht von mir beabsichtigt)[/size]

PS: statt strpbrk() sollte man jedoch vielleicht lieber ne andere Funktion die nur das Offset o.ä. zurück gibt nehmen, nen String dürfte doch mehr fressen als nen Int^^
z.B. strcspn() wie hier: php.net/manual/en/function.strpbrk.php#80934
Frage wäre nur was schneller ist :smiley: Zwar gibt das keinen String zurück, jedoch nutzt’s dafür PHP anstelle von nur C/C++/Maschinencode

Also ich habe einfach deinen RegExp genommen :stuck_out_tongue:

Und die Funktion, die in den Kommentaren zur Dokumentation steht, ist langsamer.

[code]Starte Überprüfung mit containsCharAndNumber() und 20000 Durchgängen (Teststring = ‘1234ABCxyz’).
Überprüfung abgeschlossen: 64.386129379272ms

Starte Überprüfung mit containsCharAndNumber() und 20000 Durchgängen (Teststring = ‘abcdefGHIJ’).
Überprüfung abgeschlossen: 62.55316734314ms

Starte Überprüfung mit containsCharAndNumberPos() und 20000 Durchgängen (Teststring = ‘1234ABCxyz’).
Überprüfung abgeschlossen: 85.291147232056ms

Starte Überprüfung mit containsCharAndNumberPos() und 20000 Durchgängen (Teststring = ‘abcdefGHIJ’).
Überprüfung abgeschlossen: 68.127155303955ms
[/code](Die Zeiten sind allerdings nicht mit dem vorhergehenden Benchmark vergleichbar, da ich den Test leicht verändert habe.)

Hat sich das also auch erledigt ^^

[quote=“emil”]servus leute,

erstmal danke für die vielen antworten.

= 1 :wink:
[/quote]

[quote=“emil”]servus,

kurz gefasst: ich brauche eine funktion, die prüft, ob in einem übergebenen string mindestens eine zahl und mindestens ein buchstabe enthalten sind. entsprechend boolean als rückgabe.
[/quote]

Wenn mindEinBuchstabe ∧ mindEineZahl gelten soll muss die Summe echt größer 1 sein.

... return $charMatches + $numMatches >= 2

:whata: right…

<span class="syntaxdefault">return $charMatches </span><span class="syntaxkeyword">+</span><span class="syntaxdefault"> $numMatches </span><span class="syntaxkeyword">>=</span><span class="syntaxdefault"> 2</span>würde jedoch nicht funktionieren^^ Denn wenn 2 Buchstaben vorhanden sind, aber keine Zahl, dann würde es als richtig gelten :wink:
Also lasst den Nummern Vergleich und machts so:<span class="syntaxdefault"></span><span class="syntaxkeyword">return(</span><span class="syntaxdefault">$charMatches&nbsp;</span><span class="syntaxkeyword">and&nbsp;</span><span class="syntaxdefault">$numMatches</span><span class="syntaxkeyword">)&nbsp;</span><span class="syntaxdefault"></span>

[quote=“White-Tiger”]<span class="syntaxdefault">return $charMatches </span><span class="syntaxkeyword">+</span><span class="syntaxdefault"> $numMatches </span><span class="syntaxkeyword">>=</span><span class="syntaxdefault"> 2</span>würde jedoch nicht funktionieren^^ Denn wenn 2 Buchstaben vorhanden sind, aber keine Zahl, dann würde es als richtig gelten :wink:
Also lasst den Nummern Vergleich und machts so:<span class="syntaxdefault"></span><span class="syntaxkeyword">return(</span><span class="syntaxdefault">$charMatches and $numMatches</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> </span>[/quote]

da is allerdings was dran :slight_smile:

Die logische Verknüpfung sollte wie folgt aussehen

da