Esto es en caso de que decida ir con mi comentario, sugiriendo que no use expresiones regulares. No probado (pero probablemente funciona, o al menos cerca), en Perl:
@private = (
{network => inet_aton('127.0.0.0'), mask => inet_aton('255.0.0.0') },
{network => inet_aton('192.168.0.0'), mask => inet_aton('255.255.0.0') },
# ...
);
$ip = inet_aton($ip_text);
if (grep $ip & $_->{mask} == $_->{network}, @private) {
# ip address is private
} else {
# ip address is not private
}
Nota ahora cómo @private
es sólo datos, que se pueden cambiar fácilmente. O descargue sobre la marcha desde el Cymru Bogon Reference.
editar: Se me ocurre que pedir una expresión regular de Perl no significa que conozca a Perl, por lo que la línea clave es que allí está el 'grep', que simplemente pasa por encima de cada rango de direcciones privadas. Usted toma su IP, a nivel de bit y con la máscara de red, y la compara con la dirección de red. Si es igual, es parte de esa red privada.
En primer lugar, debe revisar RFC1918 para obtener la lista apropiada. En segundo lugar, sugiero que una solución que no incluya expresiones regulares será más fácil de mantener. Una vez que convierte una dirección IP a numérica, es bastante fácil hacerla coincidir con una lista de rangos de IP privados. Esto también le permitirá usar fácilmente las listas públicas falsas, que contienen mucho más que RFC1918. – derobert
@derobert cierto, pero para usos tales como un filtro de dirección remota Tomcat necesita una expresión regular. – Raedwald
Es un error de principiante común pensar '^' significa "no" en este contexto, por lo que debe señalar: Cada '^' en su expresión simplemente ancla la coincidencia al comienzo de la línea. En la expresión regular tradicional, no hay una forma simple de decir "no esta cadena" aunque las expresiones compatibles con Perl/PCRE tienen aspectos negativos con '(?! ...)' – tripleee