O objetivo desta página é demonstrar como elaborar uma expressão que case um número IP válido.
Um número IP válido são 4 séries de números inteiros, compreendidos no intervalo de 0 a 255 (inclusive), separados por pontos. Exemplos:
0.0.0.0 4.23.156.78 120.0.0.45 127.233.255.0 255.255.255.255
Primeiro precisamos de uma ER para casar o intervalo de números inteiros entre 0 a 255. Como o intervalo [0-255] não é valido em ERs, visto que só podemos representar intervalos entre dois caracteres, fica complicado (mas não impossível) representar este intervalo com construções regulares.
Uma primeira expressão que poderia ser alcançada poderia ser uma comprida, porém fácil de entender:
ER : ([0-9]|[1-9][0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5])) casa: 0-9 | 10-99 | 100-199 | 200-249 |250-255
Funciona, mas é pouco eficiente. E lembre-se a melhor parte de ERs é passar horas para diminuí-la um caractere que seja :) Como nos dois primeiros intervalos, de 0-9 e 10-99, temos o [0-9] comum a ambos, tendo num o [1-9] e no outro não, podemos torná-lo opcional:
ER : ([1-9]?[0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5])) casa: 0-9,10-99 | 100-199 | 200-249 |250-255
Novamente, percebemos um [0-9] repetido no final dos intervalos 0-9,10-99 e 100-199. Vamos isolá-lo. SIM! É igual a matemática lá no primário! xa+xb = x(a+b)
ER : ((1[0-9]|[1-9]?)[0-9]|2([0-4][0-9]|5[0-5])) casa: 0-9,10-99,100-199 | 200-249 |250-255
Colorida e espaçada, para melhor entendimento:
( ( 1[0-9] | [1-9]? ) [0-9] | 2 ( [0-4][0-9] | 5[0-5] ) )
Sendo:
Branco : 1º nível de agrupamento Amarelo: 2º nível de agrupamento (agrupamento dentro de agrupamento) Azul : expressão dentro do 1º nível de agrupamento Verde : expressão dentro do 2º nível de agrupamento
E aqui um roteirozinho esperto em Bash com o egrep para testá-la:
#!/bin/bash a=0 # zerando a contagem while [ $a -lt 300 ] # limitando a amostragem até 300 do echo $a | egrep -x '((1[0-9]|[1-9]?)[0-9]|2([0-4][0-9]|5[0-5]))' a=$((a+1)) # incrementan a contagem done
Como um ip seria quatro vezes este intervalo, separado por pontos, algo como "0-255.0-255.0-255.0-255", teríamos, no final da brincadeira o monstro que casa um IP válido:
((1[0-9]|[1-9]?)[0-9]|2([0-4][0-9]|5[0-5]))\.((1[0-9]|[1-9]?)[0-9]|2([0-4][0-9]|5[0-5]))\.((1[0-9]|[1-9]?)[0-9]|2([0-4][0-9]|5[0-5]))\.((1[0-9]|[1-9]?)[0-9]|2([0-4][0-9]|5[0-5]))
Colorida e espaçada, para melhor entendimento:
( ( 1[0-9] | [1-9]? ) [0-9] | 2 ( [0-4][0-9] | 5[0-5] ) ) \. ( ( 1[0-9] | [1-9]? ) [0-9] | 2 ( [0-4][0-9] | 5[0-5] ) ) \. ( ( 1[0-9] | [1-9]? ) [0-9] | 2 ( [0-4][0-9] | 5[0-5] ) ) \. ( ( 1[0-9] | [1-9]? ) [0-9] | 2 ( [0-4][0-9] | 5[0-5] ) )
é claro, ao programar e precisar validar um número IP com expressões regulares, estruturas e funções da linguagem de programação ajudarão nessa tarefa, como o laço e o "split".
Ou, basta chegar uma mente aberta e sugerir outra abordagem: "(0-255.){3}0-255" (valeu Wanderlei!)
( ( ( 1[0-9] | [1-9]? ) [0-9] | 2 ( [0-4][0-9] | 5[0-5] ) ) \. ) {3} ( ( 1[0-9] | [1-9]? ) [0-9] | 2 ( [0-4][0-9] | 5[0-5] ) )