Problem mit preg_match
DiamondDogHamm
- php
Hallo Leute,
ich hab ein kleines Problem und zwar würde ich gerne prüfen ob eine gültige Proxy IP eingeben wurde.
Ich hab es mit preg_match so versucht:
if(!preg_match("§^([0-999]).([0-999]).([0-999]).([0-999]):([0-9999]])$§", mysql_real_escape_string($_POST['Proxy'])))
welches aber richtig zu seien scheind.
Wäre super wenn mir da vll jemand Helfen könnte.
Danke schon mal an alle.
Mfg Dog
Hi,
Hallo Leute,
ich hab ein kleines Problem und zwar würde ich gerne prüfen ob eine gültige Proxy IP eingeben wurde.
Ich hab es mit preg_match so versucht:
if(!preg_match("§^([0-999]).([0-999]).([0-999]).([0-999]):([0-9999]])$§", mysql_real_escape_string($_POST['Proxy'])))
> welches aber richtig zu seien scheind.
Eher nicht.
[0-999] bedeutet: eines der Zeichen 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, also (da dreifaches Aufführen der 9 nichts ändert), eines der Zeichen 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
Es bedeutet NICHT: eine Zahl zwischen 0 und 999.
Beschäftige Dich damit, was eine Zeichenklasse in Regex ist. Und mit Quantifiern (wie oft soll etwas im Regex vorkommen)
cu,
Andreas
--
[Warum nennt sich Andreas hier MudGuard?](http://MudGuard.de/)
[O o ostern ...](http://ostereier.andreas-waechter.de/)
Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.
Eher nicht.
[0-999] bedeutet: eines der Zeichen 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, also (da dreifaches Aufführen der 9 nichts ändert), eines der Zeichen 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
Es bedeutet NICHT: eine Zahl zwischen 0 und 999.Beschäftige Dich damit, was eine Zeichenklasse in Regex ist. Und mit Quantifiern (wie oft soll etwas im Regex vorkommen)
Hab das ganze zerlegt und prüfe es welches einfacher ist, siehe in derAntowrt auf den Post von dedlfix.
@@DiamondDogHamm:
nuqneH
if(!preg_match("§^([0-999]).([0-999]).([0-999]).([0-999]):([0-9999]])$§", mysql_real_escape_string($_POST['Proxy'])))
welches aber richtig zu seien scheind.
Zusätzlich zu MudGuards Hinweis: Willst du wirklich, dass '1a2b3c4:5' den Test besteht? Beachte die besondere Bedeutung von '.' in regulären Ausdrücken und dass er mit '' escapet werden muss.
Und willst du wirklich 0 bis 999 zulassen oder 0 bis 255?
Qapla'
Zusätzlich zu MudGuards Hinweis: Willst du wirklich, dass '1a2b3c4:5' den Test besteht? Beachte die besondere Bedeutung von '.' in regulären Ausdrücken und dass er mit '' escapet werden muss.
Und willst du wirklich 0 bis 999 zulassen oder 0 bis 255?
Nein wurde auch berücksichtigt, siehe Antwort an dedlfix.
Hi!
if(!preg_match("§^([0-999]).([0-999]).([0-999]).([0-999]):([0-9999]])$§", mysql_real_escape_string($_POST['Proxy'])))
welches aber richtig zu seien scheind.
Nein, ist es nicht. Zum einen ist die Verwendung von mysql_real_escape_string() an der Stelle sinnfrei. Und die anderen drei Dinge sind schon angesprochen worden. Einfacher als einen korrekten RegExp zu finden wäre, die Adresse zu zerlegen und ihre Bestandteile einzeln zu prüfen.
Lo!
Einfacher als einen korrekten RegExp zu finden wäre, die Adresse zu zerlegen und ihre Bestandteile einzeln zu prüfen.
Arrr - du warst 1 Minute schneller :)
Nein, ist es nicht.
Stimmt, weil ich dort ein nicht vergessen habe :) sorry
»»Zum einen ist die Verwendung von mysql_real_escape_string() an der Stelle sinnfrei. Und die anderen drei Dinge sind schon angesprochen worden. Einfacher als einen korrekten RegExp zu finden wäre, die Adresse zu zerlegen und ihre Bestandteile einzeln zu prüfen.
Mit dem zerlegen ist ein guter Tip, ich maches jetzt wie so:
$ip_port = explode(":", $_POST['Proxy']);
$ip_arr = explode('.',$ip_port[0]);
$port = $ip_port[1];
if ($ip_arr[0]<=255 && $ip_arr[1]<=255 && $ip_arr[2]<=255 && $ip_arr[3]<=255 && count($ip_arr) <= 4 &&
is_numeric($ip_arr[0]) && is_numeric($ip_arr[1]) && is_numeric($ip_arr[2]) && is_numeric($ip_arr[3]) &&
is_numeric($port) && $port <= 9999 &&
preg_match("!^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$!",$ip_port[0])) {
echo "IP ok!";
}else{
echo "IP fehlerhaft!";
}
bis jetzt kann ich keinen Fehler finden, wer doch noch einen Verbesserungsvorschlag hat, bitte bescheid geben.
Hi!
[code lang=php]$ip_port = explode(":", $_POST['Proxy']);
$ip_arr = explode('.',$ip_port[0]);
$port = $ip_port[1];
Geht etwas einfacher, wobei wie in deinem Code Voraussetzung ist, dass immer ein Port angegeben ist:
list($ip, $port) = explode(":", $_POST['Proxy']);
$ip_arr = explode('.', $ip);
Kennst du das Kurzschluss-Verfahren? Wenn für einen booleschen Ausdruck bereits feststeht, dass der Rest am Ergebnis nichts mehr ändern kann, wird er nicht weiter ausgewertet.
if ($ip_arr[0]<=255 && $ip_arr[1]<=255 && $ip_arr[2]<=255 && $ip_arr[3]<=255 && count($ip_arr) <= 4 &&
Du solltest hier zuerst auf die Länge 4 testen, und zwar nicht nur kleiner oder gleich, sondern genau 4. Wenn das nicht der Fall ist, kann sich PHP den Rest sparen und greift auch nicht auf dann nicht vorhandene Elemente in $ip_arr zu (spart Notice-Meldungen).
is_numeric($ip_arr[0]) && is_numeric($ip_arr[1]) && is_numeric($ip_arr[2]) && is_numeric($ip_arr[3]) && is_numeric($port) && $port <= 9999 &&
Als zweites ist die is_numeric()-Prüfung sinnvoll. is_numeric() lässt aber auch Zahlen in ungewünschter Darstellung durch, wesewgen es nur begrenzt sinnvoll ist. Hier würde ich dann doch zu einem Regexp greifen, da der die Zeichen in einem Rutsch prüfen kann.
preg_match("!^([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})$!",$ip_port[0])) {
Hast du ja schon drin, also kann die is_numeric-Prüfung weg. Der Port geht übrigens bis 65535. [0-9] kann zu \d abgekürzt werden, die Gruppierung kann entfallen.
Oder aber, du lässt sie drin und nimmst (ohne die explode()s) die Reg-Exp-Prüfung als erste (inklusive 1-5 Ziffern für den Port). Die stellt sicher, dass nur Ziffern enthalten sind und die IP nebst Port strukturell richtig ist. Mit den Gruppen kannst du anschließend die Grenzwerteinhaltung prüfen.
Lo!
Geht etwas einfacher, wobei wie in deinem Code Voraussetzung ist, dass immer ein Port angegeben ist:
list($ip, $port) = explode(":", $_POST['Proxy']);
$ip_arr = explode('.', $ip);
Ja, es muss immer ein Port angegeben sein. Habs im neuen Code berücksichtigt.
Kennst du das Kurzschluss-Verfahren? Wenn für einen booleschen Ausdruck bereits feststeht, dass der Rest am Ergebnis nichts mehr ändern kann, wird er nicht weiter ausgewertet.
if ($ip_arr[0]<=255 && $ip_arr[1]<=255 && $ip_arr[2]<=255 && $ip_arr[3]<=255 && count($ip_arr) <= 4 &&
Hab ich verstanden, wenn 1 schon murks ist ist der Rest auch murks ;)
Du solltest hier zuerst auf die Länge 4 testen, und zwar nicht nur kleiner oder gleich, sondern genau 4. Wenn das nicht der Fall ist, kann sich PHP den Rest sparen und greift auch nicht auf dann nicht vorhandene Elemente in $ip_arr zu (spart Notice-Meldungen).
Im neuen Code brücksichtigt.
is_numeric($ip_arr[0]) && is_numeric($ip_arr[1]) && is_numeric($ip_arr[2]) && is_numeric($ip_arr[3]) && is_numeric($port) && $port <= 9999 &&
Als zweites ist die is_numeric()-Prüfung sinnvoll. is_numeric() lässt aber auch Zahlen in ungewünschter Darstellung durch, wesewgen es nur begrenzt sinnvoll ist. Hier würde ich dann doch zu einem Regexp greifen, da der die Zeichen in einem Rutsch prüfen kann.
preg_match("!^([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})$!",$ip_port[0])) {
Hast du ja schon drin, also kann die is_numeric-Prüfung weg. Der Port geht übrigens bis 65535. [0-9] kann zu \d abgekürzt werden, die Gruppierung kann entfallen.
Hab die Regexp mal nach vornegesetzt und die is_nummeric rausgenommen.
Oder aber, du lässt sie drin und nimmst (ohne die explode()s) die Reg-Exp-Prüfung als erste (inklusive 1-5 Ziffern für den Port). Die stellt sicher, dass nur Ziffern enthalten sind und die IP nebst Port strukturell richtig ist. Mit den Gruppen kannst du anschließend die Grenzwerteinhaltung prüfen.
Irgend wie krieg ich es nicht hin in den Regexp Code noch den Port einzubauen, hab noch mal nachgelesen aber kp, da wäre ein wenig Hilfe vll ganz gut ;)
So sieht das ganz nun aus:
list($ip, $port) = explode(":", $_POST['Proxy'.$count]);
$ip_arr = explode('.', $ip);
if(count($ip_arr) == 4){
if (preg_match("!^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$!",$ip)&&
$ip_arr[0]<=255 && $ip_arr[1]<=255 && $ip_arr[2]<=255 && $ip_arr[3]<=255 && $port <= 65535){
echo "Ihre IPeingabe ist in Ordnung!<br>";
}else{
echo= "Ihre IPeingabe ist fehlerhaft.<br>";
}
}else{
$errors[]= "Die IPeingabe ist nicht korrekt.<br>";
}
Hi!
Oder aber, du lässt sie drin und nimmst (ohne die explode()s) die Reg-Exp-Prüfung als erste (inklusive 1-5 Ziffern für den Port). Die stellt sicher, dass nur Ziffern enthalten sind und die IP nebst Port strukturell richtig ist. Mit den Gruppen kannst du anschließend die Grenzwerteinhaltung prüfen.
Das war der Vorschlag für eine alternative Vorgehensweise, bei der nur der Regex und die Grenzwertprüfung übrigbleiben. Die Prüfung wäre dann lediglich:
if (preg_match("!^(\d{1,3}).(\d{1,3}).(\d{1,3}).(\d{1,3}):(\d{1,5)$!", $_POST..., $matches) &&
$matches[1] < 256 && $matches[2] < 256 && ... && $matches[5] < 65536)
Jetzt könnte es noch ein kleines Problem geben: vorangehende Nullen. Manche Systeme haben sich damit etwas affig. In dem Fall müsste der Regex je Gruppe etwas anders aussehen: ([1-9]\d{,2}). Benutzerfreundlicher wäre es jedoch, die Nullen in der Eingabe zuzulassen und sie selbst aus den Matches zu entfernen (z.B. mit ltrim()) und die Adresse wieder zusammenzusetzen.
Lo!
Das war der Vorschlag für eine alternative Vorgehensweise, bei der nur der Regex und die Grenzwertprüfung übrigbleiben. Die Prüfung wäre dann lediglich:
if (preg_match("!^(\d{1,3}).(\d{1,3}).(\d{1,3}).(\d{1,3}):(\d{1,5)$!", $_POST..., $matches) &&
$matches[1] < 256 && $matches[2] < 256 && ... && $matches[5] < 65536)
Hey also die Prüfung des Ports funktioniert so nicht. Vernwede ich alles mit:
:(\d{1,5)
dann funktioniert das ganze nicht. Nehme ich es aber aus dem Code, dann funktioniert alles.
@@DiamondDogHamm:
nuqneH
:(\d{1,5)
Eine Klammer ist nicht gern allein. Deshalb treten sie üblicherweise paarweise auf.
Qapla'
:(\d{1,5)
Eine Klammer ist nicht gern allein. Deshalb treten sie üblicherweise paarweise auf.
Genau da lag das Problem.
Danke.
Glaub ich hab 1000 mal drübergeschaut aber die fehlende Klammer hab ich nicht bemerkt ;)
Und nebst dessen grüßt selbstverständlich Zawinski an dieser Stelle - warum bist du mit parse_url() und filter_var() nicht zufrieden?
Und nebst dessen grüßt selbstverständlich Zawinski an dieser Stelle - warum bist du mit parse_url() und filter_var() nicht zufrieden?
Gute Frage, vll weil ich zu erst auf preg_match gestoßen bin.