Ich habe nach einer einfachen Regex für URLs gesucht, hat jemand eine praktische, die gut funktioniert? Ich habe keine mit den Zend-Framework-Validierungsklassen gefunden und mehrere Implementierungen gesehen.
PHP-Validierung/regex für URL
AndreLiem
Stanislaw
Verwenden Sie die filter_var()
Funktion zum Überprüfen, ob eine Zeichenfolge eine URL ist oder nicht:
var_dump(filter_var('example.com', FILTER_VALIDATE_URL));
Es ist keine gute Praxis, reguläre Ausdrücke zu verwenden, wenn dies nicht erforderlich ist.
BEARBEITEN: Achtung, diese Lösung ist nicht Unicode-sicher und nicht XSS-sicher. Wenn Sie eine komplexe Validierung benötigen, ist es vielleicht besser, woanders nachzusehen.
-
Es gibt einen Fehler in 5.2.13 (und ich glaube 5.3.2), der verhindert, dass URLs mit Bindestrichen mit dieser Methode validiert werden.
– vamin
1. Juni 2010 um 23:27 Uhr
-
filter_var wird abgelehnt test-site.com, ich habe Domainnamen mit Bindestrichen, unabhängig davon, ob sie gültig sind oder nicht. Ich glaube nicht, dass filter_var der beste Weg ist, eine URL zu validieren. Es erlaubt eine URL wie
http://www
– Cäsar
6. September 2010 um 19:30 Uhr
-
> Es erlaubt eine URL wie ‘www‘ Es ist in Ordnung, wenn die URL wie ‘lokaler Host‘
– Stanislaw
7. September 2010 um 10:34 Uhr
-
Das andere Problem bei dieser Methode ist, dass sie nicht Unicode-sicher ist.
– Benji XVI
10. Mai 2011 um 13:24 Uhr
-
FILTER_VALIDATE_URL hat viele Probleme die repariert werden müssen. Auch der docs, die die Flags beschreiben spiegeln die nicht wider tatsächlicher Quellcode wo Verweise auf einige Flags vollständig entfernt wurden. Mehr Infos hier: news.php.net/php.internals/99018
– S. Kobold
12. Mai 2017 um 21:53 Uhr
Owen
Ich habe dies bei einigen Projekten verwendet, ich glaube nicht, dass ich auf Probleme gestoßen bin, aber ich bin mir sicher, dass es nicht erschöpfend ist:
$text = preg_replace(
'#((https?|ftp)://(\S*?\.\S*?))([\s)\[\]{},;"\':<]|\.\s|$)#i',
"'<a href=\"$1\" target=\"_blank\">$3</a>$4'",
$text
);
Der größte Teil des zufälligen Mülls am Ende besteht darin, mit Situationen wie umzugehen http://domain.com.
in einem Satz (um zu vermeiden, dass der nachgestellte Punkt passt). Ich bin sicher, es könnte aufgeräumt werden, aber da es funktioniert hat. Ich habe es mehr oder weniger nur von Projekt zu Projekt kopiert.
-
Einige Dinge, die mir auffallen: Verwendung von Alternationen, wo Zeichenklassen verlangt werden (jede Alternative passt zu genau einem Zeichen); und die Ersetzung hätte die äußeren doppelten Anführungszeichen nicht benötigen sollen (sie wurden nur wegen des sinnlosen /e-Modifizierers in der Regex benötigt).
– Alan Moore
30. Mai 2009 um 5:53 Uhr
-
@John Scipione:
google.com
ist nur ein gültiger relativer URL-Pfad, aber keine gültige absolute URL. Und ich denke, das ist es, wonach er sucht.– Gumbo
4. Januar 2010 um 8:30 Uhr
-
Dies funktioniert in diesem Fall nicht – es enthält das nachgestellte “: 3 cantari noi in albumul audio.resursecrestine.ro/cantece/index-autori/andrei-rosu/…>
– Weichling
2. Februar 2011 um 9:06 Uhr
-
@Softy so etwas wie
http://example.com/somedir/...
ist eine vollkommen legitime URL, die nach der genannten Datei fragt...
– was ein legitimer Dateiname ist.– Stefan P
27. Juli 2011 um 23:55 Uhr
-
Ich verwende Zend\Validator\Regex, um die URL mit Ihrem Muster zu validieren, aber es wird immer noch erkannt
http://www.example
gültig sein– Joko Wandiro
26. November 2013 um 8:03 Uhr
Laut PHP-Handbuch sollte parse_url nicht verwendet werden, um eine URL zu validieren.
Leider sieht es so aus filter_var('example.com', FILTER_VALIDATE_URL)
schneidet nicht besser ab.
Beide parse_url()
und filter_var()
übergibt falsch formatierte URLs wie z http://...
Daher in diesem Fall – Regex ist die bessere Methode.
-
Dieses Argument folgt nicht. Wenn FILTER_VALIDATE_URL etwas freizügiger ist als gewünscht, fügen Sie einige zusätzliche Überprüfungen hinzu, um diese Randfälle zu bewältigen. Wenn Sie das Rad mit Ihrem eigenen Versuch einer Regex gegen URLs neu erfinden, werden Sie von einer vollständigen Prüfung nur weiter entfernt sein.
– Kzqai
19. Juli 2010 um 0:50 Uhr
-
Sehen Sie sich alle heruntergefahrenen Regexes auf dieser Seite an, um Beispiele dafür zu finden, warum Sie -nicht- Ihre eigenen schreiben sollten.
– Kzqai
19. Juli 2010 um 2:54 Uhr
-
Sie machen einen guten Punkt, Tchalvak. Regexes für so etwas wie URLs können (wie in anderen Antworten) sehr schwer richtig zu machen sein. Regex ist nicht immer die Antwort. Umgekehrt ist Regex auch nicht immer die falsche Antwort. Der wichtige Punkt ist, das richtige Werkzeug (Regex oder andere) für den Job auszuwählen und nicht speziell “anti” oder “pro” Regex zu sein. Im Nachhinein sieht Ihre Antwort auf die Verwendung von filter_var in Kombination mit Einschränkungen in den Grenzfällen wie die bessere Antwort aus (insbesondere wenn Regex-Antworten beginnen, mehr als 100 Zeichen zu erreichen – was die Wartung dieser Regex zu einem Albtraum macht).
– catchdave
20. Juli 2010 um 4:54 Uhr
Gem Johann Gruber (Gewagter Feuerball):
Regex:
(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))
Verwendung in preg_match():
preg_match("/(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))/", $url)
Hier ist das erweiterte Regex-Muster (mit Kommentaren):
(?xi)
\b
( # Capture 1: entire matched URL
(?:
https?:// # http or https protocol
| # or
www\d{0,3}[.] # "www.", "www1.", "www2." … "www999."
| # or
[a-z0-9.\-]+[.][a-z]{2,4}/ # looks like domain name followed by a slash
)
(?: # One or more:
[^\s()<>]+ # Run of non-space, non-()<>
| # or
\(([^\s()<>]+|(\([^\s()<>]+\)))*\) # balanced parens, up to 2 levels
)+
(?: # End with:
\(([^\s()<>]+|(\([^\s()<>]+\)))*\) # balanced parens, up to 2 levels
| # or
[^\s`!()\[\]{};:'".,<>?«»“”‘’] # not a space or one of these punct chars
)
)
Weitere Details finden Sie unter:
http://daringfireball.net/2010/07/improved_regex_for_matching_urls
Roger
Nur für den Fall, dass Sie wissen möchten, ob die URL wirklich existiert:
function url_exist($url){//se passar a URL existe
$c=curl_init();
curl_setopt($c,CURLOPT_URL,$url);
curl_setopt($c,CURLOPT_HEADER,1);//get the header
curl_setopt($c,CURLOPT_NOBODY,1);//and *only* get the header
curl_setopt($c,CURLOPT_RETURNTRANSFER,1);//get the response as a string from curl_exec(), rather than echoing it
curl_setopt($c,CURLOPT_FRESH_CONNECT,1);//don't use a cached version of the url
if(!curl_exec($c)){
//echo $url.' inexists';
return false;
}else{
//echo $url.' exists';
return true;
}
//$httpcode=curl_getinfo($c,CURLINFO_HTTP_CODE);
//return ($httpcode<400);
}
-
Ich würde immer noch eine Art Validierung durchführen
$url
bevor die URL tatsächlich verifiziert wird, da die obige Operation teuer ist – je nach Dateigröße vielleicht bis zu 200 Millisekunden. In manchen Fällen ist für die URL möglicherweise noch keine Ressource an ihrem Speicherort verfügbar (z. B. beim Erstellen einer URL zu einem Bild, das noch hochgeladen werden muss). Außerdem verwenden Sie keine zwischengespeicherte Version, also ist es nicht sofile_exists()
Dadurch wird eine Statistik in einer Datei zwischengespeichert und fast sofort zurückgegeben. Die von Ihnen bereitgestellte Lösung ist jedoch immer noch nützlich. Warum nicht einfach verwendenfopen($url, 'r')
?– Yzmir Ramirez
6. August 2011 um 18:14 Uhr
-
Danke, genau das, wonach ich gesucht habe. Ich habe jedoch einen Fehler gemacht, als ich versuchte, es zu verwenden. Die Funktion ist “url_exist” nicht “url_exists” oops 😉
– PJ Brunet
20. März 2012 um 20:24 Uhr
-
Besteht ein Sicherheitsrisiko beim direkten Zugriff auf die vom Benutzer eingegebene URL?
– Silikonpi
10. Mai 2012 um 7:14 Uhr
-
Sie möchten eine Überprüfung hinzufügen, ob ein 404 gefunden wurde:
$httpCode = curl_getinfo( $c, CURLINFO_HTTP_CODE ); //echo $url . ' ' . $httpCode . '
'; if( $httpCode == 404 ) {echo $url.' 404'; }– Camaleo
12. März 2018 um 13:28 Uhr
-
Ist überhaupt nicht sicher. Auf jede Eingabe-URL würde aktiv zugegriffen.
– dmm
28. Oktober 2019 um 17:36 Uhr
Kap
Ich denke nicht, dass die Verwendung regulärer Ausdrücke in diesem Fall eine kluge Sache ist. Es ist unmöglich, alle Möglichkeiten abzugleichen, und selbst wenn Sie dies getan haben, besteht immer noch die Möglichkeit, dass die URL einfach nicht existiert.
Hier ist eine sehr einfache Möglichkeit zu testen, ob die URL tatsächlich existiert und lesbar ist:
if (preg_match("#^https?://.+#", $link) and @fopen($link,"r")) echo "OK";
(wenn es keine gibt preg_match
dann würde dies auch alle Dateinamen auf Ihrem Server validieren)
-
Ich würde immer noch eine Art Validierung durchführen
$url
bevor die URL tatsächlich verifiziert wird, da die obige Operation teuer ist – je nach Dateigröße vielleicht bis zu 200 Millisekunden. In manchen Fällen ist für die URL möglicherweise noch keine Ressource an ihrem Speicherort verfügbar (z. B. beim Erstellen einer URL zu einem Bild, das noch hochgeladen werden muss). Außerdem verwenden Sie keine zwischengespeicherte Version, also ist es nicht sofile_exists()
Dadurch wird eine Statistik in einer Datei zwischengespeichert und fast sofort zurückgegeben. Die von Ihnen bereitgestellte Lösung ist jedoch immer noch nützlich. Warum nicht einfach verwendenfopen($url, 'r')
?– Yzmir Ramirez
6. August 2011 um 18:14 Uhr
-
Danke, genau das, wonach ich gesucht habe. Ich habe jedoch einen Fehler gemacht, als ich versuchte, es zu verwenden. Die Funktion ist “url_exist” nicht “url_exists” oops 😉
– PJ Brunet
20. März 2012 um 20:24 Uhr
-
Besteht ein Sicherheitsrisiko beim direkten Zugriff auf die vom Benutzer eingegebene URL?
– Silikonpi
10. Mai 2012 um 7:14 Uhr
-
Sie möchten eine Überprüfung hinzufügen, ob ein 404 gefunden wurde:
$httpCode = curl_getinfo( $c, CURLINFO_HTTP_CODE ); //echo $url . ' ' . $httpCode . '
'; if( $httpCode == 404 ) {echo $url.' 404'; }– Camaleo
12. März 2018 um 13:28 Uhr
-
Ist überhaupt nicht sicher. Auf jede Eingabe-URL würde aktiv zugegriffen.
– dmm
28. Oktober 2019 um 17:36 Uhr
Peter Bailey
Ich habe dieses mit gutem Erfolg verwendet – ich erinnere mich nicht, woher ich es habe
$pattern = "/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i";
-
^(http://|https://)?(([a-z0-9]?([-a-z0-9]*[a-z0-9]+)?){1,63}\.)+[a-z]{2,6} (kann zu gierig sein, bin mir noch nicht sicher, aber es ist flexibler in Bezug auf das Protokoll und das führende www)
– andrewbadera
26. August 2009 um 15:54 Uhr
Dies ist eine ziemlich gute Ressource. Gibt eine Liste mit vielen verschiedenen Mustern und Tests: mathiasbynens.be/demo/url-regex
– Omar J
12. November 2014 um 16:25 Uhr