2010-08-03 21 views
5

Tengo una validación de URL básica en mi aplicación. En este momento estoy usando el siguiente código.Validación de URL: acepta URL sin protocolos

//validates whether the given value is 
//a valid URL 
function validateUrl(value) 
{ 
    var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/ 
    return regexp.test(value); 
} 

Pero en este momento no está aceptando URLs sin el protocolo. Por ej. si proporciono www.google.com, no lo estoy aceptando. ¿Cómo puedo modificar el RegEx para que acepte URLs sin protocolo? protocolo

+0

Gracias por todas sus respuestas. Funcionó muy bien. – NLV

+0

Todos sus Regex están aceptando @@ ## $$ como una URL válida. ¿Algunas ideas? – NLV

+0

NLV, no especificó que quería que corrijáramos su expresión regular, solo le preguntó cómo cambiarla para aceptar cualquier protocolo. De todos modos, vea mi nueva respuesta a continuación que proporciona una expresión regular (y compleja) de validación de URL. –

Respuesta

5

Aquí es una expresión regular a largo grande para que coincide con una URL:

(?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`!()\[\]{};:'".,<>?«»“”‘’])) 

La versión expandida de que (a ayudar a hacer más comprensible):

(?xi) 
\b 
(       # Capture 1: entire matched URL 
    (?: 
    (?:[a-z][\w-]+:)?    # URL protocol and colon 
    (?: 
     /{1,3}      # 1-3 slashes 
     |        # or 
     [a-z0-9%]      # Single letter or digit or '%' 
            # (Trying not to match e.g. "URI::Escape") 
    ) 
    |       # 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 
) 
) 

Estos dos vienen de this page, pero modificado ligeramente para hacer que el protocolo sea opcional, debería leer esa página para ayudar a entender lo que está haciendo, y también tiene una variante que solo coincide con las URL basadas en la web, que también puede consultar.

+0

Gracias por su esfuerzo. Déjame revisarlo. – NLV

+2

errores en la consola de Chrome –

1

Hacer opcional con (...)?

/(((ftp|http|https):\/\/)|(\/\/))?(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/ 
+0

Esto mueve el ftp/http/https al grupo 2, y no acepta las URL '// server'. –

+0

Mira mi edición, ahora acepta 'protocol: //' o '//' o ninguna de ellas. – hsz

+0

También puede usar '(?: ...)' para excluir grupo de los resultados. – hsz

1

Cambiar la expresión regular a:

/((ftp|http|https):\/\/)?(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/ 
+0

Al igual que con la respuesta de hsz, esto mueve el ftp/http/https al grupo 2 y no acepta las URL de '// server'. –

1

no soy un experto expresiones regulares, pero que rodea el protocolo con otro soporte y el uso de un signo de interrogación al final debería hacerlo opcional:

function validateUrl(value) 
{ 
    var regexp = /((ftp|http|https):\/\/)?(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/ 
    return regexp.test(value); 
} 
+0

Nuevamente, si esta expresión regular se usó para capturar partes de URL, está creando grupos innecesarios, y está combinando incorrectamente el '//' con el protocolo, que excluye las URL válidas. –

+0

Aunque //google.com funciona, no es una URL válida y no creo que la mayoría de la gente sepa que funcionaría y, por lo tanto, puede ser muy útil excluir dichas URL de la validación. No porque sea posible, debe ser válido en todas sus formas. Las barras dobles son solo algo intermedio, ya que los puntos se encuentran entre subdominios, dominios o TLD. – 2ndkauboy

+0

Las barras dobles son el prefijo de la ruta, mientras que los dos puntos son el separador con el protocolo; son dos partes distintas que ocurren juntas. (Esto se detalla en "3. Componentes sintácticos de URI" de RFC 2396) Usando //google.com es una URL relativa válida (Nuevamente, vea el apéndice "C.1 Ejemplos normales" de RFC 2396) y ocurre "En la naturaleza". –

0

Cambiar la primera parte a:

(?:(ftp|http|https):)?(?:\/\/)? 

El contenido de grupos voluntad (?: ... ) sin usar grupos de captura (por lo que el protocolo real permanece en primer grupo).

Tenga en cuenta que las partes protocol: y // son individualmente opcionales, ya que //www.google.com es una URL válida (relativa).

+0

El colon no depende del protocolo: http://tools.ietf.org/html/rfc2396 – 2ndkauboy

+0

No está claro lo que está diciendo allí, y ese es un documento largo: ¿puede consultar la sección específica que se refiere? ¿a? Intenté (por ejemplo) ': // google.com' en Chrome e IE y no funciona, aunque parece que Firefox lo acepta. –

+0

El esquema incluye solo el nombre del protocolo (como 'http', 'ftp') pero no los dos puntos. Entonces, incluso su expresión regular no divide todos los grupos correctamente. Pero como NLV solo quería tener una expresión regular de validación para una URL válida y común (y no solo funcional), no es necesario usar un grupo alrededor de las barras diagonales. – 2ndkauboy

-1

puede validar que a continuación url favor ..

http://www.youtube.com/http://www.youtube.com/watch?v=awP_PCb67Kk

+1

Tenga en cuenta que [las respuestas de solo vínculo] (http://meta.stackoverflow.com/tags/link-only-answers/info) no se recomiendan, por lo que las respuestas deberían ser el punto final de una búsqueda para una solución (frente a otra escala más de referencias, que tienden a quedar obsoletas en el tiempo). Considere agregar una sinopsis independiente aquí, manteniendo el enlace como referencia. – kleopatra