regex - solo - simplificar expresiones regulares online
¿Cuál es la mejor expresión regular para verificar si una cadena es una URL válida? (30)
Analizador de referencia URI no validada
Para propósitos de referencia, aquí está la especificación de IETF: ( TXT | HTML ). En particular, el Apéndice B. Analizar una referencia de URI con una expresión regular demuestra cómo analizar una expresión regular válida . Esto se describe como,
para un ejemplo de un analizador de referencia URI no validada que tomará cualquier cadena dada y extraerá los componentes URI.
Aquí está la expresión regular que proporcionan:
^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(/?([^#]*))?(#(.*))?
Como dijo alguien más, probablemente es mejor dejar esto en un lib / framework que ya esté usando.
¿Cómo puedo verificar si una cadena dada es una dirección URL válida?
Mi conocimiento de las expresiones regulares es básico y no me permite elegir entre los cientos de expresiones regulares que ya he visto en la web.
¿Qué plataforma? Si usa .NET, use System.Uri.TryCreate
, no una expresión regular.
Por ejemplo:
static bool IsValidUrl(string urlString)
{
Uri uri;
return Uri.TryCreate(urlString, UriKind.Absolute, out uri)
&& (uri.Scheme == Uri.UriSchemeHttp
|| uri.Scheme == Uri.UriSchemeHttps
|| uri.Scheme == Uri.UriSchemeFtp
|| uri.Scheme == Uri.UriSchemeMailto
/*...*/);
}
// In test fixture...
[Test]
void IsValidUrl_Test()
{
Assert.True(IsValidUrl("http://www.example.com"));
Assert.False(IsValidUrl("javascript:alert(''xss'')"));
Assert.False(IsValidUrl(""));
Assert.False(IsValidUrl(null));
}
(Gracias a @Yoshi por la sugerencia sobre javascript:
@Yoshi
Acabo de escribir una publicación de blog para una excelente solución para reconocer las URL en los formatos más utilizados, como:
-
www.google.com
-
http://www.google.com
-
mailto:[email protected]
-
[email protected]
-
www.url-with-querystring.com/?url=has-querystring
La expresión regular utilizada es:
/((([A-Za-z]{3,9}:(?:////)?)(?:[-;:&=/+/$,/w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=/+/$,/w]+@)[A-Za-z0-9.-]+)((?://[/+~%//./w-_]*)?/??(?:[-/+=&;%@./w_]*)#?(?:[/w]*))?)/
Sin embargo, le recomendaría que visite http://blog.mattheworiordan.com/post/13174566389/url-regular-expression-for-links-with-or-without-the para ver el ejemplo práctico.
Con respecto a la respuesta de párpados , la publicación dice: "Esto se basa en mi lectura de la especificación de URI".: Gracias a Eyelidness, ¡la suya es la solución perfecta que busqué, ya que se basa en la especificación de URI! Excelente trabajo. :)
Tuve que hacer dos enmiendas. El primero en obtener la expresión regular para hacer coincidir las URL de las direcciones IP correctamente en PHP (v5.2.10) con la función preg_match ().
Tuve que agregar un conjunto más de paréntesis a la línea arriba de "Dirección IP" alrededor de las tuberías:
)|((/d|[1-9]/d|1/d{2}|2[0-4][0-9]|25[0-5])/.){3}(?#
No estoy seguro de por qué.
También he reducido la longitud mínima del dominio de nivel superior de 3 a 2 letras para admitir .co.uk y similares.
Código final:
/^(https?|ftp):////(?# protocol
)(([a-z0-9$_/./+!/*/'/(/),;/?&=-]|%[0-9a-f]{2})+(?# username
)(:([a-z0-9$_/./+!/*/'/(/),;/?&=-]|%[0-9a-f]{2})+)?(?# password
)@)?(?# auth requires @
)((([a-z0-9]/.|[a-z0-9][a-z0-9-]*[a-z0-9]/.)*(?# domain segments AND
)[a-z][a-z0-9-]*[a-z0-9](?# top level domain OR
)|((/d|[1-9]/d|1/d{2}|2[0-4][0-9]|25[0-5])/.){3}(?#
)(/d|[1-9]/d|1/d{2}|2[0-4][0-9]|25[0-5])(?# IP address
))(:/d+)?(?# port
))(((//+([a-z0-9$_/./+!/*/'/(/),;:@&=-]|%[0-9a-f]{2})*)*(?# path
)(/?([a-z0-9$_/./+!/*/'/(/),;:@&=-]|%[0-9a-f]{2})*)(?# query string
)?)?)?(?# path and query string optional
)(#([a-z0-9$_/./+!/*/'/(/),;:@&=-]|%[0-9a-f]{2})*)?(?# fragment
)$/i
Esta versión modificada no se comparó con la especificación de URI, por lo que no puedo garantizar su cumplimiento, se modificó para manejar las URL en los entornos de red locales y los TLD de dos dígitos, así como otros tipos de URL web, y para funcionar mejor en PHP configuración que utilizo.
Como código PHP :
define(''URL_FORMAT'',
''/^(https?):////''. // protocol
''(([a-z0-9$_/./+!/*/'/(/),;/?&=-]|%[0-9a-f]{2})+''. // username
''(:([a-z0-9$_/./+!/*/'/(/),;/?&=-]|%[0-9a-f]{2})+)?''. // password
''@)?(?#''. // auth requires @
'')((([a-z0-9]/.|[a-z0-9][a-z0-9-]*[a-z0-9]/.)*''. // domain segments AND
''[a-z][a-z0-9-]*[a-z0-9]''. // top level domain OR
''|((/d|[1-9]/d|1/d{2}|2[0-4][0-9]|25[0-5])/.){3}''.
''(/d|[1-9]/d|1/d{2}|2[0-4][0-9]|25[0-5])''. // IP address
'')(:/d+)?''. // port
'')(((//+([a-z0-9$_/./+!/*/'/(/),;:@&=-]|%[0-9a-f]{2})*)*''. // path
''(/?([a-z0-9$_/./+!/*/'/(/),;:@&=-]|%[0-9a-f]{2})*)''. // query string
''?)?)?''. // path and query string optional
''(#([a-z0-9$_/./+!/*/'/(/),;:@&=-]|%[0-9a-f]{2})*)?''. // fragment
''$/i'');
Aquí hay un programa de prueba en PHP que valida una variedad de URL usando la expresión regular:
<?php
define(''URL_FORMAT'',
''/^(https?):////''. // protocol
''(([a-z0-9$_/./+!/*/'/(/),;/?&=-]|%[0-9a-f]{2})+''. // username
''(:([a-z0-9$_/./+!/*/'/(/),;/?&=-]|%[0-9a-f]{2})+)?''. // password
''@)?(?#''. // auth requires @
'')((([a-z0-9]/.|[a-z0-9][a-z0-9-]*[a-z0-9]/.)*''. // domain segments AND
''[a-z][a-z0-9-]*[a-z0-9]''. // top level domain OR
''|((/d|[1-9]/d|1/d{2}|2[0-4][0-9]|25[0-5])/.){3}''.
''(/d|[1-9]/d|1/d{2}|2[0-4][0-9]|25[0-5])''. // IP address
'')(:/d+)?''. // port
'')(((//+([a-z0-9$_/./+!/*/'/(/),;:@&=-]|%[0-9a-f]{2})*)*''. // path
''(/?([a-z0-9$_/./+!/*/'/(/),;:@&=-]|%[0-9a-f]{2})*)''. // query string
''?)?)?''. // path and query string optional
''(#([a-z0-9$_/./+!/*/'/(/),;:@&=-]|%[0-9a-f]{2})*)?''. // fragment
''$/i'');
/**
* Verify the syntax of the given URL.
*
* @access public
* @param $url The URL to verify.
* @return boolean
*/
function is_valid_url($url) {
if (str_starts_with(strtolower($url), ''http://localhost'')) {
return true;
}
return preg_match(URL_FORMAT, $url);
}
/**
* String starts with something
*
* This function will return true only if input string starts with
* niddle
*
* @param string $string Input string
* @param string $niddle Needle string
* @return boolean
*/
function str_starts_with($string, $niddle) {
return substr($string, 0, strlen($niddle)) == $niddle;
}
/**
* Test a URL for validity and count results.
* @param url url
* @param expected expected result (true or false)
*/
$numtests = 0;
$passed = 0;
function test_url($url, $expected) {
global $numtests, $passed;
$numtests++;
$valid = is_valid_url($url);
echo "URL Valid?: " . ($valid?"yes":"no") . " for URL: $url. Expected: ".($expected?"yes":"no").". ";
if($valid == $expected) {
echo "PASS/n"; $passed++;
} else {
echo "FAIL/n";
}
}
echo "URL Tests:/n/n";
test_url("http://localserver/projects/public/assets/javascript/widgets/UserBoxMenu/widget.css", true);
test_url("http://www.google.com", true);
test_url("http://www.google.co.uk/projects/my%20folder/test.php", true);
test_url("https://myserver.localdomain", true);
test_url("http://192.168.1.120/projects/index.php", true);
test_url("http://192.168.1.1/projects/index.php", true);
test_url("http://projectpier-server.localdomain/projects/public/assets/javascript/widgets/UserBoxMenu/widget.css", true);
test_url("https://2.4.168.19/project-pier?c=test&a=b", true);
test_url("https://localhost/a/b/c/test.php?c=controller&arg1=20&arg2=20", true);
test_url("http://user:password@localhost/a/b/c/test.php?c=controller&arg1=20&arg2=20", true);
echo "/n$passed out of $numtests tests passed./n/n";
?>
Gracias de nuevo a los párpados por la expresión regular!
Escribí mi patrón de URL (en realidad, IRI, internacionalizado) para cumplir con RFC 3987 ( http://www.faqs.org/rfcs/rfc3987.html ). Estos están en sintaxis de PCRE.
Para los IRI absolutos (internacionalizados):
/^[a-z](?:[-a-z0-9/+/.])*:(?:////(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:])*@)?(?:/[(?:(?:(?:[0-9a-f]{1,4}:){6}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|::(?:[0-9a-f]{1,4}:){5}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:[0-9a-f]{1,4}:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|v[0-9a-f]+[-a-z0-9/._~!/$&''/(/)/*/+,;=:]+)/]|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}|(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=@])*)(?::[0-9]*)?(?://(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@]))*)*|//(?:(?:(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@]))+)(?://(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@]))*)*)?|(?:(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@]))+)(?://(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@]))*)*|(?!(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@])))(?:/?(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@])|[/x{E000}-/x{F8FF}/x{F0000}-/x{FFFFD}/x{100000}-/x{10FFFD}///?])*)?(?:/#(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@])|[///?])*)?$/i
Para permitir también los IRI relativos:
/^(?:[a-z](?:[-a-z0-9/+/.])*:(?:////(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:])*@)?(?:/[(?:(?:(?:[0-9a-f]{1,4}:){6}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|::(?:[0-9a-f]{1,4}:){5}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:[0-9a-f]{1,4}:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|v[0-9a-f]+[-a-z0-9/._~!/$&''/(/)/*/+,;=:]+)/]|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}|(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=@])*)(?::[0-9]*)?(?://(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@]))*)*|//(?:(?:(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@]))+)(?://(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@]))*)*)?|(?:(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@]))+)(?://(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@]))*)*|(?!(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@])))(?:/?(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@])|[/x{E000}-/x{F8FF}/x{F0000}-/x{FFFFD}/x{100000}-/x{10FFFD}///?])*)?(?:/#(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@])|[///?])*)?|(?:////(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:])*@)?(?:/[(?:(?:(?:[0-9a-f]{1,4}:){6}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|::(?:[0-9a-f]{1,4}:){5}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:[0-9a-f]{1,4}:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|v[0-9a-f]+[-a-z0-9/._~!/$&''/(/)/*/+,;=:]+)/]|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:/.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}|(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=@])*)(?::[0-9]*)?(?://(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@]))*)*|//(?:(?:(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@]))+)(?://(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@]))*)*)?|(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=@])+)(?://(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@]))*)*|(?!(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@])))(?:/?(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@])|[/x{E000}-/x{F8FF}/x{F0000}-/x{FFFFD}/x{100000}-/x{10FFFD}///?])*)?(?:/#(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9/._~/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}!/$&''/(/)/*/+,;=:@])|[///?])*)?)$/i
Cómo fueron compilados (en PHP):
<?php
/* Regex convenience functions (character class, non-capturing group) */
function cc($str, $suffix = '''', $negate = false) {
return ''['' . ($negate ? ''^'' : '''') . $str . '']'' . $suffix;
}
function ncg($str, $suffix = '''') {
return ''(?:'' . $str . '')'' . $suffix;
}
/* Preserved from RFC3986 */
$ALPHA = ''a-z'';
$DIGIT = ''0-9'';
$HEXDIG = $DIGIT . ''a-f'';
$sub_delims = ''!//$&/'//(//)//*//+,;='';
$gen_delims = ''://///?//#//[//]@'';
$reserved = $gen_delims . $sub_delims;
$unreserved = ''-'' . $ALPHA . $DIGIT . ''//._~'';
$pct_encoded = ''%'' . cc($HEXDIG) . cc($HEXDIG);
$dec_octet = ncg(implode(''|'', array(
cc($DIGIT),
cc(''1-9'') . cc($DIGIT),
''1'' . cc($DIGIT) . cc($DIGIT),
''2'' . cc(''0-4'') . cc($DIGIT),
''25'' . cc(''0-5'')
)));
$IPv4address = $dec_octet . ncg(''//.'' . $dec_octet, ''{3}'');
$h16 = cc($HEXDIG, ''{1,4}'');
$ls32 = ncg($h16 . '':'' . $h16 . ''|'' . $IPv4address);
$IPv6address = ncg(implode(''|'', array(
ncg($h16 . '':'', ''{6}'') . $ls32,
''::'' . ncg($h16 . '':'', ''{5}'') . $ls32,
ncg($h16, ''?'') . ''::'' . ncg($h16 . '':'', ''{4}'') . $ls32,
ncg($h16 . '':'' . $h16, ''?'') . ''::'' . ncg($h16 . '':'', ''{3}'') . $ls32,
ncg(ncg($h16 . '':'', ''{0,2}'') . $h16, ''?'') . ''::'' . ncg($h16 . '':'', ''{2}'') . $ls32,
ncg(ncg($h16 . '':'', ''{0,3}'') . $h16, ''?'') . ''::'' . $h16 . '':'' . $ls32,
ncg(ncg($h16 . '':'', ''{0,4}'') . $h16, ''?'') . ''::'' . $ls32,
ncg(ncg($h16 . '':'', ''{0,5}'') . $h16, ''?'') . ''::'' . $h16,
ncg(ncg($h16 . '':'', ''{0,6}'') . $h16, ''?'') . ''::'',
)));
$IPvFuture = ''v'' . cc($HEXDIG, ''+'') . cc($unreserved . $sub_delims . '':'', ''+'');
$IP_literal = ''//['' . ncg(implode(''|'', array($IPv6address, $IPvFuture))) . ''//]'';
$port = cc($DIGIT, ''*'');
$scheme = cc($ALPHA) . ncg(cc(''-'' . $ALPHA . $DIGIT . ''//+//.''), ''*'');
/* New or changed in RFC3987 */
$iprivate = ''/x{E000}-/x{F8FF}/x{F0000}-/x{FFFFD}/x{100000}-/x{10FFFD}'';
$ucschar = ''/x{A0}-/x{D7FF}/x{F900}-/x{FDCF}/x{FDF0}-/x{FFEF}'' .
''/x{10000}-/x{1FFFD}/x{20000}-/x{2FFFD}/x{30000}-/x{3FFFD}'' .
''/x{40000}-/x{4FFFD}/x{50000}-/x{5FFFD}/x{60000}-/x{6FFFD}'' .
''/x{70000}-/x{7FFFD}/x{80000}-/x{8FFFD}/x{90000}-/x{9FFFD}'' .
''/x{A0000}-/x{AFFFD}/x{B0000}-/x{BFFFD}/x{C0000}-/x{CFFFD}'' .
''/x{D0000}-/x{DFFFD}/x{E1000}-/x{EFFFD}'';
$iunreserved = ''-'' . $ALPHA . $DIGIT . ''//._~'' . $ucschar;
$ipchar = ncg($pct_encoded . ''|'' . cc($iunreserved . $sub_delims . '':@''));
$ifragment = ncg($ipchar . ''|'' . cc(''/////?''), ''*'');
$iquery = ncg($ipchar . ''|'' . cc($iprivate . ''/////?''), ''*'');
$isegment_nz_nc = ncg($pct_encoded . ''|'' . cc($iunreserved . $sub_delims . ''@''), ''+'');
$isegment_nz = ncg($ipchar, ''+'');
$isegment = ncg($ipchar, ''*'');
$ipath_empty = ''(?!'' . $ipchar . '')'';
$ipath_rootless = ncg($isegment_nz) . ncg(''///'' . $isegment, ''*'');
$ipath_noscheme = ncg($isegment_nz_nc) . ncg(''///'' . $isegment, ''*'');
$ipath_absolute = ''///'' . ncg($ipath_rootless, ''?''); // Spec says isegment-nz *( "/" isegment )
$ipath_abempty = ncg(''///'' . $isegment, ''*'');
$ipath = ncg(implode(''|'', array(
$ipath_abempty,
$ipath_absolute,
$ipath_noscheme,
$ipath_rootless,
$ipath_empty
))) . '')'';
$ireg_name = ncg($pct_encoded . ''|'' . cc($iunreserved . $sub_delims . ''@''), ''*'');
$ihost = ncg(implode(''|'', array($IP_literal, $IPv4address, $ireg_name)));
$iuserinfo = ncg($pct_encoded . ''|'' . cc($iunreserved . $sub_delims . '':''), ''*'');
$iauthority = ncg($iuserinfo . ''@'', ''?'') . $ihost . ncg('':'' . $port, ''?'');
$irelative_part = ncg(implode(''|'', array(
''//////'' . $iauthority . $ipath_abempty . '''',
'''' . $ipath_absolute . '''',
'''' . $ipath_noscheme . '''',
'''' . $ipath_empty . ''''
)));
$irelative_ref = $irelative_part . ncg(''//?'' . $iquery, ''?'') . ncg(''//#'' . $ifragment, ''?'');
$ihier_part = ncg(implode(''|'', array(
''//////'' . $iauthority . $ipath_abempty . '''',
'''' . $ipath_absolute . '''',
'''' . $ipath_rootless . '''',
'''' . $ipath_empty . ''''
)));
$absolute_IRI = $scheme . '':'' . $ihier_part . ncg(''//?'' . $iquery, ''?'');
$IRI = $scheme . '':'' . $ihier_part . ncg(''//?'' . $iquery, ''?'') . ncg(''//#'' . $ifragment, ''?'');
$IRI_reference = ncg($IRI . ''|'' . $irelative_ref);
Edición, 7 de marzo de 2011: debido a la forma en que PHP maneja las barras invertidas en cadenas entrecomilladas, éstas no se pueden usar de manera predeterminada. Tendrá que hacer doble escape de barras invertidas, excepto cuando la barra invertida tenga un significado especial en la expresión regular. Puedes hacerlo de esta manera:
$escape_backslash = ''/(?<!//)//(?![/[/]///^/$/./|/*/+/(/)QEnrtaefvdwsDWSbAZzB1-9GX]|x/{[0-9a-f]{1,4}/}|/c[A-Z]|)/'';
$absolute_IRI = preg_replace($escape_backslash, ''////', $absolute_IRI);
$IRI = preg_replace($escape_backslash, ''////', $IRI);
$IRI_reference = preg_replace($escape_backslash, ''////', $IRI_reference);
Escribí una pequeña versión genial que puedes ejecutar
coincide con las siguientes URL (que es lo suficientemente bueno para mí)
public static void main(args){
String url = "go to http://www.m.abut.ly/abc its awesome"
url = url.replaceAll(/https?:////w{0,3}/w*?/.(/w*?/.)?/w{2,3}/S*|www/.(/w*?/.)?/w*?/./w{2,3}/S*|(/w*?/.)?/w*?/./w{2,3}[///?]/S*/ , { it ->
"woof${it}woof"
})
println url
}
http://google.com/help.php?a=5
http://www.google.com/help.php
google.com?a=5
google.com/help.php
google.com/help.php?a=5
http://www.m.google.com/help.php?a=5 (y todas sus permutaciones)
www.m.google.com/help.php?a=5 (y todas sus permutaciones)
m.google.com/help.php?a=5 (y todas sus permutaciones)
Lo importante para cualquier URL que no comience con http o www es que deben incluir un / o?
Apuesto a que esto se puede ajustar un poco más, pero hace el trabajo bastante bien por ser tan corto y compacto ... porque puedes dividirlo en 3:
encuentre cualquier cosa que comience con http: https?: // w {0,3} / w *?. / w {2,3} / S *
encuentre cualquier cosa que comience con www: www. / w *?. / w {2,3} / S *
o encuentra algo que debe tener un texto, luego un punto, luego al menos 2 letras y luego una? o /: / w *?. / w {2,3} [/ /?] / S *
Esto coincidirá con todas las URL
- con o sin http / https
- con o sin www
... incluidos los subdominios y las nuevas extensiones de nombre de dominio de nivel superior, como. museo,. academia,. base, etc., que puede tener hasta 63 caracteres (no solo. com , .net,. información, etc.)
(([/w]+:)?//)?(([/d/w]|%[a-fA-f/d]{2,2})+(:([/d/w]|%[a-fA-f/d]{2,2})+)?@)?([/d/w][-/d/w]{0,253}[/d/w]/.)+[/w]{2,63}(:[/d]+)?(/([-+_~./d/w]|%[a-fA-f/d]{2,2})*)*(/?(&?([-+_~./d/w]|%[a-fA-f/d]{2,2})=?)*)?(#([-+_~./d/w]|%[a-fA-f/d]{2,2})*)?
Porque hoy en día la longitud máxima de la extensión de nombre de dominio de nivel superior disponible es de 13 caracteres, como. internacional , puede cambiar el número 63 en la expresión a 13 para evitar que alguien lo use mal.
como javascript
var urlreg=/(([/w]+:)?////)?(([/d/w]|%[a-fA-f/d]{2,2})+(:([/d/w]|%[a-fA-f/d]{2,2})+)?@)?([/d/w][-/d/w]{0,253}[/d/w]/.)+[/w]{2,63}(:[/d]+)?(//([-+_~./d/w]|%[a-fA-f/d]{2,2})*)*(/?(&?([-+_~./d/w]|%[a-fA-f/d]{2,2})=?)*)?(#([-+_~./d/w]|%[a-fA-f/d]{2,2})*)?/;
$(''textarea'').on(''input'',function(){
var url = $(this).val();
$(this).toggleClass(''invalid'', urlreg.test(url) == false)
});
$(''textarea'').trigger(''input'');
textarea{color:green;}
.invalid{color:red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea>http://www.google.com</textarea>
<textarea>http//www.google.com</textarea>
<textarea>googlecom</textarea>
<textarea>https://www.google.com</textarea>
Artículo de Wikipedia: lista de todos los dominios de nivel superior de Internet
Esto es lo que RegexBuddy utiliza.
(/b(https?|ftp|file)://)?[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]
Coincide con estos debajo (dentro de las marcas ** **
):
**http://www.regexbuddy.com**
**http://www.regexbuddy.com/**
**http://www.regexbuddy.com/index.html**
**http://www.regexbuddy.com/index.html?source=library**
Puede descargar RegexBuddy en http://www.regexbuddy.com/download.html .
He estado trabajando en un artículo detallado sobre la validación de URI utilizando expresiones regulares. Se basa en RFC3986.
Validación de URI de Expresión Regular
Aunque el artículo aún no está completo, se me ocurrió una función PHP que hace un buen trabajo de validación de las URL de HTTP y FTP. Aquí está la versión actual:
// function url_valid($url) { Rev:20110423_2000
//
// Return associative array of valid URI components, or FALSE if $url is not
// RFC-3986 compliant. If the passed URL begins with: "www." or "ftp.", then
// "http://" or "ftp://" is prepended and the corrected full-url is stored in
// the return array with a key name "url". This value should be used by the caller.
//
// Return value: FALSE if $url is not valid, otherwise array of URI components:
// e.g.
// Given: "http://www.jmrware.com:80/articles?height=10&width=75#fragone"
// Array(
// [scheme] => http
// [authority] => www.jmrware.com:80
// [userinfo] =>
// [host] => www.jmrware.com
// [IP_literal] =>
// [IPV6address] =>
// [ls32] =>
// [IPvFuture] =>
// [IPv4address] =>
// [regname] => www.jmrware.com
// [port] => 80
// [path_abempty] => /articles
// [query] => height=10&width=75
// [fragment] => fragone
// [url] => http://www.jmrware.com:80/articles?height=10&width=75#fragone
// )
function url_valid($url) {
if (strpos($url, ''www.'') === 0) $url = ''http://''. $url;
if (strpos($url, ''ftp.'') === 0) $url = ''ftp://''. $url;
if (!preg_match(''/# Valid absolute URI having a non-empty, valid DNS host.
^
(?P<scheme>[A-Za-z][A-Za-z0-9+/-.]*):////
(?P<authority>
(?:(?P<userinfo>(?:[A-Za-z0-9/-._~!$&/'()*+,;=:]|%[0-9A-Fa-f]{2})*)@)?
(?P<host>
(?P<IP_literal>
/[
(?:
(?P<IPV6address>
(?: (?:[0-9A-Fa-f]{1,4}:){6}
| ::(?:[0-9A-Fa-f]{1,4}:){5}
| (?: [0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}
| (?:(?:[0-9A-Fa-f]{1,4}:){0,1}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}
| (?:(?:[0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}
| (?:(?:[0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})?:: [0-9A-Fa-f]{1,4}:
| (?:(?:[0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})?::
)
(?P<ls32>[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}
| (?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/.){3}
(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)
)
| (?:(?:[0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})?:: [0-9A-Fa-f]{1,4}
| (?:(?:[0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})?::
)
| (?P<IPvFuture>[Vv][0-9A-Fa-f]+/.[A-Za-z0-9/-._~!$&/'()*+,;=:]+)
)
/]
)
| (?P<IPv4address>(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/.){3}
(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))
| (?P<regname>(?:[A-Za-z0-9/-._~!$&/'()*+,;=]|%[0-9A-Fa-f]{2})+)
)
(?::(?P<port>[0-9]*))?
)
(?P<path_abempty>(?://(?:[A-Za-z0-9/-._~!$&/'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*)
(?:/?(?P<query> (?:[A-Za-z0-9/-._~!$&/'()*+,;=:@///?]|%[0-9A-Fa-f]{2})*))?
(?:/#(?P<fragment> (?:[A-Za-z0-9/-._~!$&/'()*+,;=:@///?]|%[0-9A-Fa-f]{2})*))?
$
/mx'', $url, $m)) return FALSE;
switch ($m[''scheme'']) {
case ''https'':
case ''http'':
if ($m[''userinfo'']) return FALSE; // HTTP scheme does not allow userinfo.
break;
case ''ftps'':
case ''ftp'':
break;
default:
return FALSE; // Unrecognized URI scheme. Default to FALSE.
}
// Validate host name conforms to DNS "dot-separated-parts".
if ($m[''regname'']) { // If host regname specified, check for DNS conformance.
if (!preg_match(''/# HTTP DNS host name.
^ # Anchor to beginning of string.
(?!.{256}) # Overall host length is less than 256 chars.
(?: # Group dot separated host part alternatives.
[A-Za-z0-9]/. # Either a single alphanum followed by dot
| # or... part has more than one char (63 chars max).
[A-Za-z0-9] # Part first char is alphanum (no dash).
[A-Za-z0-9/-]{0,61} # Internal chars are alphanum plus dash.
[A-Za-z0-9] # Part last char is alphanum (no dash).
/. # Each part followed by literal dot.
)* # Zero or more parts before top level domain.
(?: # Explicitly specify top level domains.
com|edu|gov|int|mil|net|org|biz|
info|name|pro|aero|coop|museum|
asia|cat|jobs|mobi|tel|travel|
[A-Za-z]{2}) # Country codes are exactly two alpha chars.
/.? # Top level domain can end in a dot.
$ # Anchor to end of string.
/ix'', $m[''host''])) return FALSE;
}
$m[''url''] = $url;
for ($i = 0; isset($m[$i]); ++$i) unset($m[$i]);
return $m; // return TRUE == array of useful named $matches plus the valid $url.
}
Esta función utiliza dos expresiones regulares; uno para que coincida con un subconjunto de URI genéricos válidos (los absolutos que tienen un host no vacío), y un segundo para validar el nombre de host "partes separadas por puntos" del DNS. Aunque esta función actualmente solo valida los esquemas HTTP y FTP, está estructurada de tal manera que se puede extender fácilmente para manejar otros esquemas.
La mejor expresión regular para la URL para mí sería:
"(([/w]+:)?//)?(([/d/w]|%[a-fA-F/d]{2,2})+(:([/d/w]|%[a-fA-f/d]{2,2})+)?@)?([/d/w][-/d/w]{0,253}[/d/w]/.)+[/w]{2,4}(:[/d]+)?(/([-+_~./d/w]|%[a-fA-f/d]{2,2})*)*(/?(&?([-+_~./d/w]|%[a-fA-f/d]{2,2})=?)*)?(#([-+_~./d/w]|%[a-fA-f/d]{2,2})*)?"
La publicación Obtención de partes de una URL (Regex) analiza el análisis de una URL para identificar sus diversos componentes. Si desea comprobar si una URL está bien formada, debería ser suficiente para sus necesidades.
Si necesita comprobar si es realmente válido, finalmente tendrá que intentar acceder a lo que esté en el otro extremo.
Sin embargo, en general, probablemente esté mejor usando una función que le proporcione su marco u otra biblioteca. Muchas plataformas incluyen funciones que analizan URLs. Por ejemplo, hay urlparse módulo urlparse de Python, y en .NET puede usar el constructor de la clase System.Uri como un medio para validar la URL.
Mathias Bynens tiene un gran artículo sobre la mejor comparación de muchas expresiones regulares: en busca de la expresión perfecta de validación de URL
El mejor publicado es un poco largo, pero coincide con casi cualquier cosa que puedas lanzarle.
Versión de JavaScript
/^(?:(?:https?|ftp):////)(?:/S+(?::/S*)?@)?(?:(?!(?:10|127)(?:/./d{1,3}){3})(?!(?:169/.254|192/.168)(?:/./d{1,3}){2})(?!172/.(?:1[6-9]|2/d|3[0-1])(?:/./d{1,3}){2})(?:[1-9]/d?|1/d/d|2[01]/d|22[0-3])(?:/.(?:1?/d{1,2}|2[0-4]/d|25[0-5])){2}(?:/.(?:[1-9]/d?|1/d/d|2[0-4]/d|25[0-4]))|(?:(?:[a-z/u00a1-/uffff0-9]-*)*[a-z/u00a1-/uffff0-9]+)(?:/.(?:[a-z/u00a1-/uffff0-9]-*)*[a-z/u00a1-/uffff0-9]+)*(?:/.(?:[a-z/u00a1-/uffff]{2,}))/.?)(?::/d{2,5})?(?:[/?#]/S*)?$/i
Versión PHP
_^(?:(?:https?|ftp)://)(?:/S+(?::/S*)?@)?(?:(?!(?:10|127)(?:/./d{1,3}){3})(?!(?:169/.254|192/.168)(?:/./d{1,3}){2})(?!172/.(?:1[6-9]|2/d|3[0-1])(?:/./d{1,3}){2})(?:[1-9]/d?|1/d/d|2[01]/d|22[0-3])(?:/.(?:1?/d{1,2}|2[0-4]/d|25[0-5])){2}(?:/.(?:[1-9]/d?|1/d/d|2[0-4]/d|25[0-4]))|(?:(?:[a-z/x{00a1}-/x{ffff}0-9]-*)*[a-z/x{00a1}-/x{ffff}0-9]+)(?:/.(?:[a-z/x{00a1}-/x{ffff}0-9]-*)*[a-z/x{00a1}-/x{ffff}0-9]+)*(?:/.(?:[a-z/x{00a1}-/x{ffff}]{2,}))/.?)(?::/d{2,5})?(?:[/?#]/S*)?$_iuS
No pude encontrar la expresión regular que estaba buscando, así que modifiqué una expresión regular para cumplir mis requisitos, y al parecer parece que ahora funciona bien. Mis requerimientos fueron:
- Coincidir las URL con el protocolo (www.gooogle.com)
- Haga coincidir las URL con los parámetros de consulta y la ruta ( http://subdomain.web-site.com/cgi-bin/perl.cgi?key1=value1&key2=value2e )
- No coincida con las URL donde no hay caracteres aceptables (por ejemplo, "''£), por ejemplo: (www.google.com/somthing"/somethingmore)
Aquí lo que se me ocurrió, cualquier sugerencia es apreciada:
@Test
public void testWebsiteUrl(){
String regularExpression = "((http|ftp|https)://////)?[//w//-_]+(//.[//w//-_]+)+([//w//-//.,@?^=%&:/~//+#]*[//w//-//@?^=%&/~//+#])?";
assertTrue("www.google.com".matches(regularExpression));
assertTrue("www.google.co.uk".matches(regularExpression));
assertTrue("http://www.google.com".matches(regularExpression));
assertTrue("http://www.google.co.uk".matches(regularExpression));
assertTrue("https://www.google.com".matches(regularExpression));
assertTrue("https://www.google.co.uk".matches(regularExpression));
assertTrue("google.com".matches(regularExpression));
assertTrue("google.co.uk".matches(regularExpression));
assertTrue("google.mu".matches(regularExpression));
assertTrue("mes.intnet.mu".matches(regularExpression));
assertTrue("cse.uom.ac.mu".matches(regularExpression));
assertTrue("http://www.google.com/path".matches(regularExpression));
assertTrue("http://subdomain.web-site.com/cgi-bin/perl.cgi?key1=value1&key2=value2e".matches(regularExpression));
assertTrue("http://www.google.com/?queryparam=123".matches(regularExpression));
assertTrue("http://www.google.com/path?queryparam=123".matches(regularExpression));
assertFalse("www..dr.google".matches(regularExpression));
assertFalse("www:google.com".matches(regularExpression));
assertFalse("https://[email protected]".matches(regularExpression));
assertFalse("https://www.google.com/"".matches(regularExpression));
assertFalse("https://www.google.com''".matches(regularExpression));
assertFalse("http://www.google.com/path''".matches(regularExpression));
assertFalse("http://subdomain.web-site.com/cgi-bin/perl.cgi?key1=value1&key2=value2e''".matches(regularExpression));
assertFalse("http://www.google.com/?queryparam=123''".matches(regularExpression));
assertFalse("http://www.google.com/path?queryparam=12''3".matches(regularExpression));
}
Si realmente busca la coincidencia definitiva , probablemente la encuentre en "¿ Una buena expresión regular de url? ".
Pero una expresión regular que realmente coincida con todos los dominios posibles y permita que cualquier cosa permitida de acuerdo con los RFC sea terriblemente larga e ilegible, créame ;-)
Yo uso esta expresión regular:
((https?:)?//)?(([/d/w]|%[a-fA-f/d]{2,2})+(:([/d/w]|%[a-fA-f/d]{2,2})+)?@)?([/d/w][-/d/w]{0,253}[/d/w]/.)+[/w]{2,63}(:[/d]+)?(/([-+_~./d/w]|%[a-fA-f/d]{2,2})*)*(/?(&?([-+_~./d/w]|%[a-fA-f/d]{2,2})=?)*)?(#([-+_~./d/w]|%[a-fA-f/d]{2,2})*)?
Para apoyar tanto:
http://.com
https://.com
Y:
//.com
¿Qué hay de malo con FILTER_VALIDATE_URL?
$url = "http://www.example.com";
if(!filter_var($url, FILTER_VALIDATE_URL))
{
echo "URL is not valid";
}
else
{
echo "URL is valid";
}
Sé que no es exactamente la pregunta, pero hizo el trabajo por mí cuando necesitaba validar las URL, así que pensé que podría ser útil para otros que se encuentren en esta publicación en busca de lo mismo.
Es posible que este no sea un trabajo para expresiones regulares, sino para las herramientas existentes en el idioma que elija. Probablemente desee utilizar el código existente que ya se ha escrito, probado y depurado.
En PHP, use la función parse_url
.
Perl: módulo URI
.
Ruby: módulo URI
.
.NET: clase ''Uri''
Las expresiones regulares no son una varita mágica que usted agita ante cada problema que involucra cuerdas.
El siguiente RegEx funcionará:
"@((((ht)|(f))tp[s]?://)|(www/.))([a-z][-a-z0-9]+/.)?([a-z][-a-z0-9]+/.)?[a-z][-a-z0-9]+/.[a-z]+[/]?[a-z0-9._//~#&=;%+?-]*@si"
Espero que te sea útil ...
^(http|https):////+[/www/d]+/.[/w]+(//[/w/d]+)?
Esta me funciona muy bien. (https?|ftp)://(www/d?|[a-zA-Z0-9]+)?/.[a-zA-Z0-9-]+(/:|/.)([a-zA-Z0-9.]+|(/d+)?)([/?:].*)?
Para Python, esta es la expresión regular de validación de URL utilizada en Django 1.5.1:
import re
regex = re.compile(
r''^(?:http|ftp)s?://'' # http:// or https://
r''(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?/.)+(?:[A-Z]{2,6}/.?|[A-Z0-9-]{2,}/.?)|'' # domain...
r''localhost|'' # localhost...
r''/d{1,3}/./d{1,3}/./d{1,3}/./d{1,3}|'' # ...or ipv4
r''/[?[A-F0-9]*:[A-F0-9:]+/]?)'' # ...or ipv6
r''(?::/d+)?'' # optional port
r''(?:/?|[/?]/S+)$'', re.IGNORECASE)
Esto hace tanto las direcciones ipv4 como ipv6, así como los puertos y los parámetros GET.
Encontrado en el código aquí , línea 44.
Para comprobar la expresión regular de URL sería:
^http(s{0,1})://[a-zA-Z0-9_///-//.]+//.([A-Za-z/]{2,5})[a-zA-Z0-9_///&//?//=//-//.//~//%]*
Usa este está trabajando para mí
function validUrl(Url) {
var myRegExp =/^(?:(?:https?|ftp):////)(?:/S+(?::/S*)?@)?(?:(?!10(?:/./d{1,3}){3})(?!127(?:/./d{1,3}){3})(?!169/.254(?:/./d{1,3}){2})(?!192/.168(?:/./d{1,3}){2})(?!172/.(?:1[6-9]|2/d|3[0-1])(?:/./d{1,3}){2})(?:[1-9]/d?|1/d/d|2[01]/d|22[0-3])(?:/.(?:1?/d{1,2}|2[0-4]/d|25[0-5])){2}(?:/.(?:[1-9]/d?|1/d/d|2[0-4]/d|25[0-4]))|(?:(?:[a-z/u00a1-/uffff0-9]+-?)*[a-z/u00a1-/uffff0-9]+)(?:/.(?:[a-z/u00a1-/uffff0-9]+-?)*[a-z/u00a1-/uffff0-9]+)*(?:/.(?:[a-z/u00a1-/uffff]{2,})))(?::/d{2,5})?(?://[^/s]*)?$/i;
if (!RegExp.test(Url.value)) {
$("#urlErrorLbl").removeClass(''highlightNew'');
return false;
}
$("#urlErrorLbl").addClass(''highlightNew'');
return true;
}
Aquí hay una versión de Java lista para usar del código fuente de Android. Este es el mejor que he encontrado.
public static final Matcher WEB = Pattern.compile(new StringBuilder()
.append("((?:(http|https|Http|Https|rtsp|Rtsp):")
.append("//////(?:(?:[a-zA-Z0-9//$//-//_//.//+//!//*//'//(//)")
.append("//,//;//?//&//=]|(?://%[a-fA-F0-9]{2})){1,64}(?://:(?:[a-zA-Z0-9//$//-//_")
.append("//.//+//!//*//'//(//)//,//;//?//&//=]|(?://%[a-fA-F0-9]{2})){1,25})?//@)?)?")
.append("((?:(?:[a-zA-Z0-9][a-zA-Z0-9//-]{0,64}//.)+") // named host
.append("(?:") // plus top level domain
.append("(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])")
.append("|(?:biz|b[abdefghijmnorstvwyz])")
.append("|(?:cat|com|coop|c[acdfghiklmnoruvxyz])")
.append("|d[ejkmoz]")
.append("|(?:edu|e[cegrstu])")
.append("|f[ijkmor]")
.append("|(?:gov|g[abdefghilmnpqrstuwy])")
.append("|h[kmnrtu]")
.append("|(?:info|int|i[delmnoqrst])")
.append("|(?:jobs|j[emop])")
.append("|k[eghimnrwyz]")
.append("|l[abcikrstuvy]")
.append("|(?:mil|mobi|museum|m[acdghklmnopqrstuvwxyz])")
.append("|(?:name|net|n[acefgilopruz])")
.append("|(?:org|om)")
.append("|(?:pro|p[aefghklmnrstwy])")
.append("|qa")
.append("|r[eouw]")
.append("|s[abcdeghijklmnortuvyz]")
.append("|(?:tel|travel|t[cdfghjklmnoprtvwz])")
.append("|u[agkmsyz]")
.append("|v[aceginu]")
.append("|w[fs]")
.append("|y[etu]")
.append("|z[amw]))")
.append("|(?:(?:25[0-5]|2[0-4]") // or ip address
.append("[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])//.(?:25[0-5]|2[0-4][0-9]")
.append("|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)//.(?:25[0-5]|2[0-4][0-9]|[0-1]")
.append("[0-9]{2}|[1-9][0-9]|[1-9]|0)//.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}")
.append("|[1-9][0-9]|[0-9])))")
.append("(?://://d{1,5})?)") // plus option port number
.append("(///(?:(?:[a-zA-Z0-9//;/////?//://@//&//=//#//~") // plus option query params
.append("//-//.//+//!//*//'//(//)//,//_])|(?://%[a-fA-F0-9]{2}))*)?")
.append("(?://b|$)").toString()
).matcher("");
Encontré el siguiente Regex para URL, probado con más de 500 URL :
//b(?:(?:https?|ftp):////)(?:/S+(?::/S*)?@)?(?:(?!10(?:/./d{1,3}){3})(?!127(?:/./d{1,3}){3})(?!169/.254(?:/./d{1,3}){2})(?!192/.168(?:/./d{1,3}){2})(?!172/.(?:1[6-9]|2/d|3[0-1])(?:/./d{1,3}){2})(?:[1-9]/d?|1/d/d|2[01]/d|22[0-3])(?:/.(?:1?/d{1,2}|2[0-4]/d|25[0-5])){2}(?:/.(?:[1-9]/d?|1/d/d|2[0-4]/d|25[0-4]))|(?:(?:[az/x{00a1}-/x{ffff}0-9]+-?)*[az/x{00a1}-/x{ffff}0-9]+)(?:/.(?:[az/x{00a1}-/x{ffff}0-9]+-?)*[az/x{00a1}-/x{ffff}0-9]+)*(?:/.(?:[az/x{00a1}-/x{ffff}]{2,})))(?::/d{2,5})?(?://[^/s]*)?/b/gi
Sé que se ve feo, pero lo bueno es que funciona. :)
Explicación y demostración con 581 URL aleatorias en regex101.
Intenté formular mi versión de url. Mi requerimiento era capturar instancias en una cadena donde la url posible puede ser cse.uom.ac.mu - señalando que no está precedido por http ni www
String regularExpression = "((((ht{2}ps?://)?)((w{3}//.)?))?)[^.&&[a-zA-Z0-9]][a-zA-Z0-9.-]+[^.&&[a-zA-Z0-9]](//.[a-zA-Z]{2,3})";
assertTrue("www.google.com".matches(regularExpression));
assertTrue("www.google.co.uk".matches(regularExpression));
assertTrue("http://www.google.com".matches(regularExpression));
assertTrue("http://www.google.co.uk".matches(regularExpression));
assertTrue("https://www.google.com".matches(regularExpression));
assertTrue("https://www.google.co.uk".matches(regularExpression));
assertTrue("google.com".matches(regularExpression));
assertTrue("google.co.uk".matches(regularExpression));
assertTrue("google.mu".matches(regularExpression));
assertTrue("mes.intnet.mu".matches(regularExpression));
assertTrue("cse.uom.ac.mu".matches(regularExpression));
//cannot contain 2 ''.'' after www
assertFalse("www..dr.google".matches(regularExpression));
//cannot contain 2 ''.'' just before com
assertFalse("www.dr.google..com".matches(regularExpression));
// to test case where url www must be followed with a ''.''
assertFalse("www:google.com".matches(regularExpression));
// to test case where url www must be followed with a ''.''
//assertFalse("http://wwwe.google.com".matches(regularExpression));
// to test case where www must be preceded with a ''.''
assertFalse("https://[email protected]".matches(regularExpression));
No especifica qué idioma está utilizando. Si PHP es, hay una función nativa para eso:
$url = ''http://www.yoururl.co.uk/sub1/sub2/?param=1¶m2/'';
if ( ! filter_var( $url, FILTER_VALIDATE_URL ) ) {
// Wrong
}
else {
// Valid
}
Devuelve los datos filtrados, o FALSE si el filtro falla.
Espero eso ayude.
Para su comodidad, aquí hay una expresión regular de una sola línea para las URL que también coincidirá con localhost, donde es más probable que tenga puertos .com
o similares.
(http(s)?:////.)?(www/.)?[-a-zA-Z0-9@:%._/+~#=]{2,256}(/.[a-z]{2,6}|:[0-9]{3,4})/b([-a-zA-Z0-9@:%_/+.~#?&////=]*)
function validateURL(textval) {
var urlregex = new RegExp(
"^(http|https|ftp)/://[a-zA-Z0-9/-/.]+/.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?([a-zA-Z0-9/-/._/?/,/'////+&%/$#/=~])*$");
return urlregex.test(textval);
}
Partidos http://www.asdah.com/~joe | ftp://ftp.asdah.co.uk:2828/asdah%20asdah.gif | https://asdah.gov/asdh-ah.as
function validateURL(textval) {
var urlregex = new RegExp(
"^(http|https|ftp)/://([a-zA-Z0-9/./-]+(/:[a-zA-Z0-9/.&%/$/-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])/.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)/.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)/.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9/-]+/.)*[a-zA-Z0-9/-]+/.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(/:[0-9]+)*(/($|[a-zA-Z0-9/./,/?/'///+&%/$#/=~_/-]+))*$");
return urlregex.test(textval);
}
Coincide con http://site.com/dir/file.php?var=moo | ftp://user:[email protected]:21/file/dir
Site.com que no coincide con los partidos | http://site.com/dir//