¿Qué hay de malo con la expresión regular listada para usar con una dirección IP?

Algunas observaciones:

  • Su expresión regular solo funcionará con IPv4, con la notación decimal punto (1)
  • Como señaló Lee Byron, permitirá direcciones IP como 999.999.999.999, que no es válida.
  • Debería usar literales de expresión regular, para evitar el doble escape, y esto es (creo) más sencillo de escribir. En lugar de escribir esto:
    var r = new RegExp("my\\.regex", "gi");
    puedes escribir esto:
    var r = /my\.regex/gi;
    Tenga en cuenta que deberá escapar de las barras inclinadas, y no le permite crear expresiones regulares dinámicas (como en el new RegExp("foo"+bar, flags) ).
  • No necesita usar el método exec cuando solo desea verificar si una expresión regular coincide con una cadena, es más eficiente usar el método de test , que devuelve true o false .

Parece que desea escribir una función única para validar entradas basadas en una expresión regular dada. Aquí hay una versión reescrita que usa literales de expresiones regulares y un objeto para almacenar expresiones regulares:

 var regexes = { // Here we store the regular expressions // Your regular expression ip : /[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/gi }; function validInput(userInput, inputType) { // If there's no regular expression for this input type, that is, there's // no inputType's value key in the 'regexes' object. if (!(inputType in regexes)) { return false; } return regexes[inputType].test(userInput); } 

Entonces, llamarás a la función así:

 var badIPIsValid = validInput("999.999.999.999", "ip"); alert(badIPIsValid); // true (for now) 

Ahora veamos la expresión regular:

  1. Como señaló Evan Priestley, es mejor usar \d lugar de [0-9] :
    /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/gi
  2. Aquí, es inútil tener la bandera “i”, ya que usamos números, y la bandera “g”, ya que estamos validando una dirección IP. Entonces podemos despojarlos:
    /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/
  3. La expresión regular también funciona para cadenas como "phone number : 1.456.789.0 :)" , porque solo estamos probando si la expresión regular puede coincidir con una parte de la cadena, pero no con toda la cadena. Así que agreguemos un símbolo de intercalación ( ^ ) al comienzo, para que coincida con el comienzo de la cadena, y un signo de dólar ( $ ) al final para que coincida con el final de la cadena:
    /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/
  4. Todavía tenemos el problema "999.999.999.999" . Creo que la forma más fácil de hacerlo es usar la función de Lee Byron, pero intentemos usar una expresión regular. El primer desafío es hacer una expresión regular que coincida solo con enteros positivos por debajo de 256. Aquí hay uno:
    /^(?:(?:0|1)?\d{1,2}|2(?:[0-4]\d|5[0-5]))$/
    Coincide con números que comienzan con un 0 o 1 seguido de uno o dos dígitos, o números con solo uno o dos dígitos, o números que comienzan con un 2 y seguidos por un número entre 0 y 4 (incluido) y un dígito, o por un 5 seguido de un número entre 0 y 5.

    Ahora es fácil, tenemos que usar la expresión regular cuatro veces:
    /^(?:(?:0|1)?\d{1,2}|2(?:[0-4]\d|5[0-5]))\.(?:(?:0|1)?\d{1,2}|2(?:[0-4]\d|5[0-5]))\.(?:(?:0|1)?\d{1,2}|2(?:[0-4]\d|5[0-5]))\.(?:(?:0|1)?\d{1,2}|2(?:[0-4]\d|5[0-5]))$/

  5. Opcionalmente, puede acortar la expresión regular:
    /^(?:(?:(?:0|1)?\d{1,2}|2(?:[0-4]\d|5[0-5]))\.){3}(?:(?:0|1)?\d{1,2}|2(?:[0-4]\d|5[0-5]))$/
  6. Así que aquí estamos, aquí está el código completo:
     var regexes = { // Here we store the regular expressions // Your regular expression ip : /^(?:(?:(?:0|1)?\d{1,2}|2(?:[0-4]\d|5[0-5]))\.){3}(?:(?:0|1)?\d{1,2}|2(?:[0-4]\d|5[0-5]))$/ }; function validInput(userInput, inputType) { // If there's no regular expression for this input type, that is, there's // no inputType's value key in the 'regexes' object. if (!(inputType in regexes)) { return false; } // .test is more efficient than .match when you just // want to test if a regular expression matches a string. return regexes[inputType].test(userInput); } 

    También puede acortar la función validInput :

     function validInput(userInput, inputType) { return ((inputType in regexes) && regexes[inputType].test(userInput)); } 

Usando las tablas de direcciones válidas que se muestran en [1], podemos probar nuestra implementación con una serie de pruebas:

 var valid, isValidIPv4; valid = { yes: [ "0.0.0.0", "10.0.0.0", "100.64.0.0", "127.0.0.0", "169.254.0.0", "172.16.0.0", "192.0.0.0", "192.0.2.0", "192.88.99.0", "192.168.0.0", "198.18.0.0", "198.51.100.0", "203.0.113.0", "224.0.0.0", "240.0.0.0", "255.255.255.255" ], no: [ "999.999.999.999", 0, "", null, undefined, NaN, "string", [], {}, true, 1 ] }; isValidIPv4 = function( value ) { return validInput( value, "ip" ); }; Object.keys(valid).forEach(function( type, k ) { var expect = type === "yes" ? true : false; console.log( valid[ type ].filter(function( value ) { var result = isValidIPv4(value); if ( isValidIPv4(value) === expect ) { // If the test passes, it's filtered from the list return false; } console.log( "TEST FAILED", value ); return true; }).length === 0 ? "PASS" : "FAIL" ); }); // The expected output should be: "PASS" "PASS" 

Notas:
[1]: Hay otras anotaciones, cf: http://en.wikipedia.org/wiki/IPv…

La respuesta de Evan Priestley es un excelente comienzo para las cosas que debes considerar. Aquí hay algunos otros:

Los números en una dirección IP están limitados a 0-255, por lo que [0-9] {1,3} permitirá “999” que no es válido.

Muchos rangos de direcciones IP están reservados: http://en.wikipedia.org/wiki/Res
Finalmente, su expresión regular solo maneja direcciones IPv4. Debe decidir si desea limitar su aplicación para que no use IPv6.

Si bien es posible escribir una expresión regular para validar las direcciones IP, no es fácil y probablemente no será fácil de leer. Aquí hay un ejemplo grosero: http: //www.regular-expressions.i… . Probablemente sea mucho más fácil hacer esto sin una expresión regular:

 function isValidIPv4(ip) { var addresses = ip.split("."); if (addresses.length != 4) { return false; } for (var i = 0; i < 4; i++) { var address = addresses[i]; if (!isFinite(address) || address < 0 || address > 255) { return false; } } return true; } 

Este script es casi correcto, solo necesita algunos pequeños ajustes.

Primero, debe preferir \d sobre [0-9] al hacer coincidir dígitos, porque es más conciso y hace que su programa sea más robusto en caso de que la IANA defina nuevos dígitos. La definición de \d se actualizará automáticamente para incluir los nuevos dígitos, pero la clase de caracteres manual [0-9] no lo hará (y, por supuesto, lo mismo ocurre si los dígitos están en desuso).

Segundo, cuando escribes \. en un literal de cadena, no está escapando el período para usar en la expresión regular, solo para usar en la cadena. El valor real de la cadena no retiene la barra invertida. Puede verificar esto en la consola:

  >>> "\."
 "." 

Entonces, después de interpretar el literal de cadena, el valor tiene puntos: [0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3} . Esto coincide con muchas cadenas que no desea, como 7Q5~321 .

Puedes escapar de las barras diagonales inversas para que sobrevivan hasta la expresión regular. Para estar seguro de que todo llega intacto, también puede conservar el escape original, ¡ciertamente no puede doler!

var validRegExPattern = "\\\d\{1\,3\}\\\.\\\d\{1\,3\}\\\.\\\d\{1\,3\}\\\.\\\d\{1\,3\}"

Finalmente, no hay suficientes pruebas contra el valor de isValid.exec(userInput) . Debes cubrir todas tus bases:

  if (isValid.exec (userInput) == "" ||
 isValid.exec (userInput) == "nulo" ||
 isValid.exec (userInput) == null ||
 isValid.exec (userInput) == '' ||
 isValid.exec (userInput) == false ||
 isValid.exec (userInput) == "false" ||
 isValid.exec (userInput) == 0 ||
 isValid.exec (userInput) == "0" ||
 isValid.exec (userInput) == [] ||
 isValid.exec (userInput) == {} ||
 isValid.exec (userInput) == "cadena vacía" ||
 isValid.exec (userInput) == "no" ||
 isValid.exec (userInput) == "FALSE" ||
 isValid.exec (userInput) == 0.0 ||
 isValid.exec (userInput) == NaN ||
 isValid.exec (userInput) == Number.NEGATIVE_INFINITY) {
   ...
 }

Con estos pequeños cambios, el programa debería funcionar correctamente.

// javascript

// para direcciones IP válidas; Paso esta variable a la siguiente función cuando es apropiado
var validRegExPattern = “^ (? 🙁 ?: 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]?) $ ”

función isValidInput (userInput, validRegExPattern)
{
// modificadores: i = mayúsculas y minúsculas, g = global, coincidencia de líneas múltiples
var isValid = new RegExp (validRegExPattern, “gi”);

//alert(isValid.exec(userInput));

if (isValid.exec (userInput) === “” || isValid.exec (userInput) === “null” || isValid.exec (userInput) === null ||
isValid.exec (userInput) === falso || isValid.exec (userInput) === “false” || isValid.exec (userInput) === 0 ||
isValid.exec (userInput) === “0” || isValid.exec (userInput) === [] || isValid.exec (userInput) === {} ||
isValid.exec (userInput) === “cadena vacía” || isValid.exec (userInput) === “no” || isValid.exec (userInput) === “FALSO” ||
isValid.exec (userInput) === 0.0 || isValid.exec (userInput) === NaN || isValid.exec (userInput) === Number.NEGATIVE_INFINITY) {
falso retorno;
} más {
volver verdadero;
}
}

Lo anterior es a lo que cambié mi función en función de sus comentarios y sugerencias. Gracias a todos. Esto funciona muy bien

Tenga en cuenta que usé un triple “=” b / c, no deberíamos escribir valores de conversión aquí.

More Interesting

¿Puedes localizar una dirección IP de una cuenta de correo electrónico eliminada?

¿Qué porcentaje de las solicitudes de oferta de RTB incluyen una dirección IP? De esos, ¿qué porcentaje incluye todos los octetos?

¿Qué tipo de dominio se usa para configurar servidores de nombres, y tiene que ser un dominio de registro? Si es así, ¿a qué dirección IP debe apuntar el dominio?

¿Es posible cambiar la dirección MAC de Wi-Fi de mi teléfono?

¿Por qué la escasez de direcciones de Internet se convierte en un problema?

¿Cuál es el procedimiento para cambiar la dirección MAC de un Lenovo A7000?

Desde la misma computadora, ubicación y conexión de red, ¿por qué mi dirección IP cambia de un día para otro entre varias direcciones IP, pero con mayor frecuencia entre 2.98.xxx.23 y 78.150.xxx.185?

Tengo la dirección IP de alguien, ¿cómo puedo encontrar sus perfiles de correo electrónico o redes sociales?

¿Cómo puede alguien en la red Tor rastrear mi dirección IP incluso si estoy usando Tor, una VPN y TAILS?

¿Por qué ya no necesitamos configurar las direcciones IP y escribir entradas DNS?

¿Cómo funciona una dirección IP estática en redes de computadoras?

¿Cómo puedo configurar el SLA IP en un enrutador de la serie Cisco 1921?

Cómo seguir cambiando mi dirección IP local

¿Qué es el filtrado de direcciones Mac?

Dado que las direcciones IPv4 de 4 bytes se han agotado, ¿se agotarán las direcciones MAC de 6 bytes antes de que se agoten las direcciones IPv6 de 16 bytes? ¿Se tomarán medidas?