La expresión regular valida una IP incorrecta porque coincide con sólo una parte de ésta

publicado por: Anonymous

Tengo la siguiente expresión regular:

(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])|(localhost)

Mi intención es que valide tanto una IP como la palabra localhost.

El problema está en que, por ejemplo, me traga 256.255.255.255.

Lo estoy probando en esta página http://www.regexr.com/

  • introduciendo 255.255.255.255, me coge como válido 255.255.255.2
  • y si introduzco 256.255.255.255, me coge como válido 56.255.255.2.

Ese es el código que uso para validar la expresión.

var hostExp = "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])|(localhost)";

function checkHost() {
   return $("#host").val().match(hostExp) ? true : false;
}

¿Alguien tiene idea de que tengo mal o que funciona mal?

solución

Nada está funcionando mal. Tu expresión es correcta. Sólo hay que considerar un tema importante:

Las expresiones regulares intentan coincidir con una subcadena en cualquier lugar del texto.

Para exigirle que sólo pueda coincidir con el texto completo, se deben utilizar las anclas ^ y $, que coinciden con el inicio y el final del string respectivamente.

var hostExp =  /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(localhost)$/;

if (hostExp.test(texto)) {

}

Además, algunos puntos extra a tener en cuenta. Hay partes de tu expresión que no es necesario agrupar (tiene algunos paréntesis de más), y cuando uno agrupa, suele ser recomendable usar grupos sin captura.

(?:expresión) es exactamente lo mismo que (expresión), con el beneficio de que no utiliza memoria para capturar el texto que coincidió con ese subpatrón.

Aprovecho además para acortarla un poco.

_x000D_

_x000D_

var texto = "255.255.255.255";_x000D_
_x000D_
var hostExp = /^(?:(?:[1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}(?:[1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^localhost$/;_x000D_
_x000D_
if (hostExp.test(texto)) {_x000D_
    console.log("Coincide con " + texto);_x000D_
}

_x000D_

_x000D_

_x000D_

  • se siguió la intención del autor, de no aceptar números con 0 a la izquierda.

Alternativamente, si quisieras que coincida con una IP dentro de otro texto, podrías utilizar límites de palabra completa: b.

/b(?:(?:[1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}(?:[1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])b|blocalhostb/

Ejemplo:
https://regex101.com/r/6UEpy2/1

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *