2010-10-11 15 views
9

Ich möchte eine URL-Link in der Wand posten und diesen Link mit Anker-Tag ersetzen, dafür verwende ich den regulären Ausdruck unten.Übereinstimmung URL-Muster in PHP mit regulären Ausdruck

würde ich das Match 4 Arten von URL wie:

  1. http://example.com
  2. https://example.com
  3. www.example.com
  4. example.com
preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)@', 
      '<a href="$1">$1</a>', $subject); 

Dieser Ausdruck stimmt nur mit den ersten beiden URL-Typen überein.

Wenn ich diesen Ausdruck für Übereinstimmung URL-Muster '@(www?([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)@' verwenden, dann entspricht es nur die dritte Art von URL-Muster.

Wie kann ich alle vier Arten von URL-Mustern mit einem einzigen regulären Ausdruck abgleichen?

Antwort

14

Ich würde einen anderen Regex verwenden, um ehrlich zu sein. Wie diese, dass Gruber posted 2009:

\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))) 

oder diese aktualisierte Version, die Gruber posted 2010 (danke, @IMSoP):

(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’])) 
+2

Hinweis hilft, dass es eine neuere Version hier dieser regex ist: http://daringfireball.net/2010/ 07/enhanced_regex_for_matching_urls – IMSoP

+2

Implementiert in PHP: [http://stackoverflow.com/a/10002262/1055533](http://stackoverflow.com/a/10002262/1055533) – Oskar

0

Wenn Sie möchten, dass eine Arbeit, die Sie brauchen, um machen Sie den "https? //" Teil optional, da Sie ein ziemlich gutes Verständnis von Regexps zu haben scheinen, werde ich Ihnen nicht zeigen, ein excerise für den Leser :)

Aber ich stimme generell mit Nev überein, es ist übermäßig kompliziert für was es tut.

14

Ein komplettes Arbeits Beispiel Nev Stokes Link mithilfe gegeben:

public function clickableUrls($html){ 
    return $result = preg_replace(
     '%\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))%s', 
     '<a href="$1">$1</a>', 
     $html 
    ); 
} 
+0

meine Güte, endlich funktioniert dieses ... Ich habe alle Arten von denen versucht, die Leute gepostet haben, entweder Probleme mit der Syntax oder sie funktionieren teilweise (was ich reparieren musste, war das th Es gab Zeiten am Ende der URL, die abgeholt wurden, wie t.co/123213 ...) – kn00tcn

+0

Ja, funktioniert super! – Ben

1

Ich habe gerade überprüft diesen Beitrag (nach 2 Jahren) könnten Sie die Antwort bekommen, aber für diejenigen, die Anfänger sind, können Sie regelmäßig verwenden Ausdruck jede Art von URL oder Query String

(https|http|ftp)\:\/\/|([a-z0-9A-Z]+\.[a-z0-9A-Z]+\.[a-zA-Z]{2,4})|([a-z0-9A-Z]+\.[a-zA-Z]{2,4})|\?([a-zA-Z0-9]+[\&\=\#a-z]+) 

es wird jede Art von URLs Streifen, werfen sie einen Blick auf die folgende Liste zu entfernen. Ich habe verschiedene Arten von Domains für diejenigen, die „wird es abzustreifen .us, .in oder .pk etc Art von Domains oder nicht.

  1. ftp://www.web.com
  2. web.net
  3. www.website stellen wollen .info
  4. website.us
  5. web.ws?query=true
  6. www.web.biz?query=true
  7. ftp://web.in?query=true
  8. media.google.com
  9. ns.google.pk
  10. ww1.smart.au
  11. www3.smart.br
  12. w1.smart.so
  13. ? ques == zwei & t = p
  14. http://website.info?ques==two&t=p
  15. https://www.weborwebsite.com

Arbeitsbeispiel (in PHP5 +, Apache2 + getestet):

$str = "ftp://www.web.com, web.net, www.website.info, website.us, web.ws?query=true, www.web.biz?query=true, ftp://web.in?query=true, media.google.com hello world, working more with ns ns.google.pk or ww1.smart.au and www3.smart.br w1.smart.so ?ques==two&t=p http://website.info?ques==two&t=p https://www.weborwebsite.com and ftp://www.hotmail.br"; 
echo preg_replace("/(https|http|ftp)\:\/\/|([a-z0-9A-Z]+\.[a-z0-9A-Z]+\.[a-zA-Z]{2,4})|([a-z0-9A-Z]+\.[a-zA-Z]{2,4})|\?([a-zA-Z0-9]+[\&\=\#a-z]+)/i", "", $str); 

wird es

, , , , , , , hello world, working more with ns or and and 

zurückkehren Hoffe, dass es da draußen eine Menge Programmierer hilft

2

Ich sah mich um und war nicht sehen, die genau waren, was ich brauchte. Ich fand this one, die nahe war, so dass ich es geändert wie folgt:

^((([hH][tT][tT][pP][sS]?)\:\/\/)?([\w\\-]+(\[\w\.\&%\$\-]+)*)?((([^\s\(\)\<\>\\\"\.\ [\]\,;:]+)(\.[^\s\(\)\<\>\\\"\.\[\]\,;:]+)*(\.[a-zA-Z]{2,4}))|((([01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}([01]?\d{1,2}|2[0-4]\d|25[0-5])))(\b\:(6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3}|0)\b)?((\/[^\/][\w\.\,\?\'\\\/\+&%\$#\=~_\-]*)*[^\.\,\?\"\'\(\)\[\]!;<>{}\s\x7F-\xFF])?)$ 

, check it out auf debuggex.

0

Verwenden Sie dieses Muster.

$regex = "(https?\:\/\/|ftp\:\/\/|www\.|[a-z0-9-]+)+([a-z0-9-]+)\.+([a-z]{2,4})((\/|\.)+([a-z0-9-_.\/]*)$|$)"; 

hoffe, dass hilfreich.

0

Meine zwei Cent (fünf Jahre später!):

preg_match("/^((https|http|ftp)\:\/\/)?([a-z0-9A-Z]+\.[a-z0-9A-Z]+\.[a-z0-9A-Z]+\.[a-zA-Z]{2,4}|[a-z0-9A-Z]+\.[a-z0-9A-Z]+\.[a-zA-Z]{2,4}|[a-z0-9A-Z]+\.[a-zA-Z]{2,4})$/i", $url) 

Hoffe, dass es jemand

Verwandte Themen