Regex de PHP para validar una URL

Estoy buscando una expresión regular decente para que coincida con una URL (una URL completa con esquema, dominio, ruta, etc.). Normalmente usaría filter_var pero no puedo en este caso, ya que tengo que soportar PHP <5.2.

He buscado en la web pero no encuentro nada que confíe que sea infalible, y todo lo que puedo encontrar en SO es que la gente dice que use filter_var.

¿Alguien tiene una expresión regular que usan para esto?

Mi código (para que pueda ver lo que estoy tratando de lograr):

function validate_url($url){ if (function_exists('filter_var')){ return filter_var($url, FILTER_VALIDATE_URL); } return preg_match(REGEX_HERE, $url); } 

Podrías probar este . No lo he probado, pero seguramente es la expresión regular más grande que he visto en mi vida, jaja.

 ^(?#Protocol)(?:(?:ht|f)tp(?:s?)\:\/\/|~\/|\/)?(?#Username:Password)(?:\w+:\[email protected])?(?#Subdomains)(?:(?:[-\w]+\.)+(?#TopLevel Domains)(?:com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum|travel|[az]{2}))(?#Port)(?::[\d]{1,5})?(?#Directories)(?:(?:(?:\/(?:[-\w~!$+|.,=]|%[af\d]{2})+)+|\/)+|\?|#)?(?#Query)(?:(?:\?(?:[-\w~!$+|.,*:]|%[af\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[af\d]{2})*)(?:&(?:[-\w~!$+|.,*:]|%[af\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[af\d]{2})*)*)*(?#Anchor)(?:#(?:[-\w~!$+|.,*:=]|%[af\d]{2})*)?$ 

He creado una solución para validar el dominio. Si bien no cubre específicamente toda la URL, es muy detallada y específica. La pregunta que debe hacerse es: “¿Por qué estoy validando un dominio?” Si es para ver si el dominio realmente podría existir, entonces necesita confirmar el dominio (incluidos los TLD válidos). El problema es que muchos desarrolladores toman el atajo de ([az] {2,4}) y lo llaman bueno. Si piensas en estas líneas, ¿por qué lo llamas validación de URL? No es. Solo está pasando la URL a través de una expresión regular.

Tengo una clase de código abierto que le permitirá validar el dominio no solo usando la fuente única para la administración de TLD (iana.org), sino que también validará el dominio mediante registros DNS para asegurarse de que realmente exista. La validación de DNS es opcional, pero el dominio será específicamente válido en función de TLD.

Por ejemplo: example.ay NO es un dominio válido ya que el dominio .ay TLD no es válido. Pero usando la expresión regular publicada aquí ([az] {2,4}), pasaría. Tengo una afinidad por la calidad. Intento express eso en el código que escribo. A otros tal vez no les importe. Entonces, si desea simplemente “verificar” la URL, puede usar los ejemplos que figuran en estas respuestas. Si realmente quiere validar el dominio en la URL, puede tener en la clase que creé para hacer precisamente eso. Se puede descargar en: http://code.google.com/p/blogchuck/source/browse/trunk/domains.php

Valida en base a las RFC que “gobiernan” (usando el término libremente) lo que determina un dominio válido. En pocas palabras, esto es lo que hará la clase de dominios: reglas básicas de la validación de dominio

  • debe tener al menos un carácter largo
  • debe comenzar con una letra o número
  • contiene letras, números y guiones
  • debe terminar en una carta o número
  • puede contener múltiples nodos (es decir, node1.node2.node3)
  • cada nodo solo puede tener 63 caracteres de longitud como máximo
  • el nombre de dominio total solo puede tener 255 caracteres como máximo
  • debe terminar en un TLD válido
  • puede ser una dirección IP4

También descargará una copia del archivo maestro de TLD iana.org solo después de verificar su copia local. Si su copia local está vencida por 30 días, descargará una nueva copia. Los TLD del archivo se usarán en el REGEX para validar el TLD en el dominio que está validando. Esto evita que el .ay (y otros TLD inválidos) apruebe la validación.

Este es un código muy largo, pero muy compacto teniendo en cuenta lo que hace. Y es el más preciso. Es por eso que hice la pregunta antes. ¿Desea hacer “validación” o simple “comprobación”?

He visto una expresión regular que en realidad podría validar cualquier tipo de URL válida, pero tenía dos páginas …

Probablemente sea mejor que parse_url la URL con parse_url y luego parse_url si todos sus bits requeridos están en orden.

Además: Este es un recorte de mi clase de URL:

 public static function IsUrl($test) { if (strpos($test, ' ') > -1) { return false; } if (strpos($test, '.') > 1) { $check = @parse_url($test); return is_array($check) && isset($check['scheme']) && isset($check['host']) && count(explode('.', $check['host'])) > 1 } return false; } 

Prueba la cadena dada y requiere algunos conceptos básicos en la url, es decir, que el esquema está establecido y el nombre de host tiene un punto.

 !(https?://)?([-_a-z0-9]+\.)*([-_a-z0-9]+)\.([az]{2,4})(/?)(.*)!i 

Yo uso esta expresión regular para validar URLs. Hasta ahora no me ha fallado ni una sola vez 🙂