2010-10-11 15 views
9

Quiero hacer coincidir un enlace de url en la publicación de la pared y reemplazar este enlace con la etiqueta de anclaje, para esto utilizo la expresión regular a continuación.coincide con el patrón de url en php usando la expresión regular

Me gustaría que el partido 4 tipos de URL:

  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); 

Esta expresión solo coincide con los dos primeros tipos de url.

Si utilizo esta expresión para el patrón '@(www?([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)@', solo coincide con el tercer tipo de patrón de url.

¿Cómo puedo unir los cuatro tipos de patrón de URL con una sola expresión regular?

Respuesta

14

Usaría una expresión regular diferente para ser sincero. Al igual que éste que Gruber posted en 2009:

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

o esta versión actualizada que Gruber posted en 2010 (gracias, @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

en cuenta que hay una versión más reciente de esa expresión regular aquí: http://daringfireball.net/2010/ 07/improved_regex_for_matching_urls – IMSoP

+2

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

0

Si usted quiere hacer que un trabajo que necesita hacer que la parte "https? //" sea opcional, ya que parece que tienes una buena comprensión de las expresiones regulares, no te mostraré, un excerise para el lector :)

Pero generalmente estoy de acuerdo con Nev, es demasiado complicado por lo que hace

14

un ejemplo de trabajo completo utilizando Nev Stokes dado enlace:

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

mi bondad, finalmente este funciona ... He estado probando todo tipo de cosas que la gente ha publicado, o tienen problemas con la sintaxis o trabajan parcialmente (lo que necesitaba corregir era que Hubo períodos al final de la url que se estaban recogiendo, como t.co/123213 ...) – kn00tcn

+0

¡Sí, funciona genial! – Ben

1

acabo de revisar este post (después de 2 años) podría ser que tienes la respuesta, pero para aquellos que son principiantes, puede utilizar regularmente expresión para despojar a todos los tipos de URL o de cadena de consulta

(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]+) 

que se tira de cada tipo de URL, echar un vistazo a la siguiente lista. He utilizado diferentes tipos de dominios para los que quieren preguntar "va a despojar .us, .en o .pk etc tipo de dominios o no.

  1. ftp://www.web.com
  2. web.net
  3. www.website .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 dos & t = p
  14. http://website.info?ques==two&t=p
  15. https://www.weborwebsite.com

Ejemplo de trabajo (probado en PHP5 +, Apache2 +):

$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); 

volverá

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

creo que sirve una gran cantidad de codificadores por ahí

2

Miré alrededor y no vi ninguna que eran exactamente lo que necesitaba. He encontrado this one que estaba cerca, así que lo modificó de la siguiente manera:

^((([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])?)$ 

comprobarlo en debuggex.

0

utilice este patrón.

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

espero que sea útil.

0

Mis dos centavos (cinco años después!):

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) 

espero que ayude a alguien

Cuestiones relacionadas