Validando endereços IPv4 com regexp


94

Tenho tentado obter um regex eficiente para validação IPv4, mas sem muita sorte. Em um ponto parecia que eu estava farto (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}, mas produz alguns resultados estranhos:

$ grep --version
grep (GNU grep) 2.7
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.1.1
192.168.1.1
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.1.255
192.168.1.255
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.255.255
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.1.2555
192.168.1.2555

Fiz uma pesquisa para ver se isso já tinha sido perguntado e respondido, mas outras respostas parecem simplesmente mostrar como determinar 4 grupos de 1-3 números ou não funcionam para mim.


13
Não se esqueça de que A, AB e ABC são formas válidas de endereço IP, assim como ABCD a sério. Experimente ping 2130706433e ping 127.1dê uma risadinha.
dty

1
Minha variante online regexr.com/39hqf
Sllouyssgort

Respostas:


98

Você já tem uma resposta funcional, mas apenas no caso de estar curioso sobre o que há de errado com sua abordagem original, a resposta é que você precisa de parênteses em torno de sua alternância, caso contrário, ele (\.|$)só será necessário se o número for inferior a 200.

'\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b'
    ^                                    ^

26
isso parece também validar coisas como192.168.1.1.1
cwd

2
Deve ser \b((?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:(?<!\.)\b|\.)){4}:; ou seja, termina com um limite de palavra em vez de com o final da linha? Além disso, marquei os grupos de não captura para evitar sub-correspondências indesejadas. NB: Isso ainda não leva em consideração o comentário de @dty, pois não estou familiarizado com essa forma de IP; embora ele esteja certo de que parece válido.
JohnLBevan,

Em vez disso, você pode tentar: ((1? \ D \ d? | 2 [0-4] \ d | 25 [0-5]) \.) {3} (1? \ D \ d? | 2 [0-4] \ d | 25 [0-5])
Morg.

Isso funciona bem para não capturar -\b(?:(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b
Appy

3
É 09.09.09.09considerado um IP válido? Ele também é correspondido por esta regex. Mas o ping lança mensagem de erro como ping: cannot resolve 09.09.09.09: Unknown host. Acho que pode ser sábio reduzir a correspondência apenas para correspondência de notação ponto-decimal. Esta entrada discute os principais erros em endereços IP.
Ruifeng Ma

82
^((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]?)$

Aceite :

127.0.0.1
192.168.1.1
192.168.1.255
255.255.255.255
0.0.0.0
1.1.1.01        # This is an invalid IP address!

Rejeitar :

30.168.1.255.1
127.1
192.168.1.256
-1.2.3.4
1.1.1.1.
3...3

Experimente online com testes de unidade: https://www.debuggex.com/r/-EDZOqxTxhiTncN6/1


e o endereço IP "3 ... 3"? 3 ... 3 é aceito usando esta regex
Ankur Loriya

8
E quanto a 1.1.1.01? É considerado um endereço IPv4 válido? Obrigado.
odieatla

esta regexp 1.1.1.01 considera um endereço IPv4 VÁLIDO. Testes de unidade online debuggex.com/r/-EDZOqxTxhiTncN6/1
Sllouyssgort

a propósito, ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}$obtenha o mesmo resultado debuggex.com/r/mz_-0dEm3wseIKqK , bastante semelhante à resposta de
@Mark

@PriteshAcharya Funciona bem aqui.
Kid Diamond

41

Versão mais recente, mais curta e menos legível ( 55 caracteres )

^((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}$

Esta versão procura o case 250-5, depois disso ela habilmente ORs todos os cases possíveis para os 200-249 100-199 10-99cases. Observe que a |)parte não é um erro, mas, na verdade, é o último caso para o intervalo 0-9. Também omiti a ?:parte do grupo de não captura, pois não nos importamos com os itens capturados, eles não seriam capturados de qualquer maneira se não tivéssemos uma correspondência completa em primeiro lugar.

Versão antiga e mais curta (menos legível) ( 63 caracteres )

^(?:(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(?!$)|$)){4}$

Versão mais antiga (legível) ( 70 caracteres )

^(?:(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(\.(?!$)|$)){4}$

Ele usa o lookahead negativo (?!)para remover o caso em que o ip pode terminar com um.

Resposta mais antiga ( 115 caracteres )

^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}
    (?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$

Eu acho que este é o regex mais preciso e estrito, ele não aceita coisas como 000.021.01.0.parece que a maioria das outras respostas aqui fazem e requer regex adicional para rejeitar casos semelhantes a esse - ou seja, 0números iniciais e um ip que termina com um.


Esta é a única resposta correta neste tópico até esta data. Os outros perdem endereços como 0.0.0.0ou aceitam notação octal / decimal mista como 033.033.33.033ou mesmo permitem 999.999.999.999. Que tal este regex que é 10 caracteres mais curto do que esta resposta:(([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])
anneb

1
@tinmarino Reverti sua edição porque permitia coisas como 192.168.000.1, que não é um endereço válido. Quem quiser editar esta resposta, por favor, comente primeiro aqui para evitar problemas como esses - eu geralmente respondo bem rápido. Sempre procurando uma solução mais curta / melhor, é claro.
Danail Gabenski

1
@DanailGabenski (e outros) para memória, você resolveu substituindo [01]?[0-9][0-9]?por último 1[0-9]{2}|[1-9]?[0-9]porque você não gosta de colocar 0 . Agradeço mais uma vez ! Vou manter sua solução na minha bagagem regex master.
Tinmarino

1
@tinmarino sim, o formato ponto-decimal que se tornou padrão para ipv4, embora não seja oficialmente aceito, por favor, veja o seguinte . Especificamente no ponto 3, onde um projeto foi sugerido, mas expirou. Uma razão secundária para ser tão rígido com a validação é que, quando apresentados na IU, os ips com números não decimais como 023 em vez de 23 fazem os usuários acharem que isso é um erro / bug. Isso também causa dificuldades com a verificação / segurança, pois 023 precisa ser convertido para 23 para evitar duplicatas, etc. Obrigado por tentar melhorar as coisas!
Danail Gabenski

1
Você pode torná-lo mais curto por factoring o [0-9]para os 2[0-4], 1e mais curtos casos. ^(?:(25[0-5]|(?:2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}$
Clayton Singh

11

Endereço IPv4 (captura precisa) Corresponde a 0.0.0.0 a 255.255.255.255, mas captura endereços inválidos, como 1.1.000.1 Use este regex para combinar números IP com precisão. Cada um dos 4 números é armazenado em um grupo de captura, para que você possa acessá-los para processamento posterior.

\b
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)
\b

retirado da biblioteca JGsoft RegexBuddy

Edit: esta (\.|$)parte parece estranha


2
Agradável! Fiz uma modificação mais eficiente do que parece funcionar: "\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$){4}\b- obrigado!
Matthieu Cartier

2
@MatthieuCartier Seu padrão de regex eficiente não funcionou para mim,
R__raki__

1
255.255.255.000 não é um IP válido
Stéphane GRILLON

6

Eu estava em busca de algo semelhante para endereços IPv4 - um regex que também impediu que endereços IP privados comumente usados ​​fossem validados (192.168.xy, 10.xyz, 172.16.xy), então usei análises futuras negativas para fazer isso:

(?!(10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.).*)
(?!255\.255\.255\.255)(25[0-5]|2[0-4]\d|[1]\d\d|[1-9]\d|[1-9])
(\.(25[0-5]|2[0-4]\d|[1]\d\d|[1-9]\d|\d)){3}

(Devem estar em uma linha, é claro, formatados para fins de legibilidade em 3 linhas separadas) Visualização de expressão regular

Demo Debuggex

Pode não ser otimizado para velocidade, mas funciona bem quando procura apenas endereços de Internet 'reais'.

Coisas que irão (e devem) falhar:

0.1.2.3         (0.0.0.0/8 is reserved for some broadcasts)
10.1.2.3        (10.0.0.0/8 is considered private)
172.16.1.2      (172.16.0.0/12 is considered private)
172.31.1.2      (same as previous, but near the end of that range)
192.168.1.2     (192.168.0.0/16 is considered private)
255.255.255.255 (reserved broadcast is not an IP)
.2.3.4
1.2.3.
1.2.3.256
1.2.256.4
1.256.3.4
256.2.3.4
1.2.3.4.5
1..3.4

IPs que irão (e devem) funcionar:

1.0.1.0         (China)
8.8.8.8         (Google DNS in USA)
100.1.2.3       (USA)
172.15.1.2      (USA)
172.32.1.2      (USA)
192.167.1.2     (Italy)

Fornecido no caso de alguém estar procurando validar 'endereços IP da Internet não incluindo os endereços privados comuns'


5

Acho que muitas pessoas que estão lendo este post procurarão expressões regulares mais simples, mesmo que elas correspondam a alguns endereços IP tecnicamente inválidos. (E, conforme observado em outro lugar, regex provavelmente não é a ferramenta certa para validar adequadamente um endereço IP de qualquer maneira.)

Remova ^e, quando aplicável, substitua $por \b, se não quiser fazer a correspondência do início / fim da linha.

Expressão regular básica (BRE) (testado em GNU grep, GNU sed e vim):

/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/

Expressão regular estendida (ERE):

/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/

ou:

/^([0-9]+(\.|$)){4}/

Expressão regular compatível com Perl (PCRE) (testado em Perl 5.18):

/^\d+\.\d+\.\d+\.\d+$/

ou:

/^(\d+(\.|$)){4}/

Ruby (testado em Ruby 2.1):

Embora supostamente PCRE, Ruby, por qualquer motivo, permitiu esta regex não permitida pelo Perl 5.18:

/^(\d+[\.$]){4}/

Meus testes para todos estes estão online aqui .


3

É um pouco mais longo do que alguns, mas é o que uso para fazer a correspondência de endereços IPv4. Simples, sem compromissos.

^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$

3

As respostas acima são válidas, mas e se o endereço IP não estiver no final da linha e estiver entre o texto ... Este regex funcionará até mesmo nisso.

código: '\b((([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]))\b'

arquivo de texto de entrada:

ip address 0.0.0.0 asfasf
 sad sa 255.255.255.255 cvjnzx
zxckjzbxk  999.999.999.999 jshbczxcbx
sjaasbfj 192.168.0.1 asdkjaksb
oyo 123241.24121.1234.3423 yo
yo 0000.0000.0000.0000 y
aw1a.21asd2.21ad.21d2
yo 254.254.254.254 y0
172.24.1.210 asfjas
200.200.200.200
000.000.000.000
007.08.09.210
010.10.30.110

texto de saída:

0.0.0.0
255.255.255.255
192.168.0.1
254.254.254.254
172.24.1.210
200.200.200.200

1
Isso foi marcado negativamente, até que eu dei um voto. Tenho tentado fazer exatamente isso (mais horas do que quero admitir). Ele não irá capturar uma linha que tenha mais de um ponto-quádruplo em uma linha, mas para o meu caso de uso, posso viver com isso. Esta é uma excelente resposta, precisa de mais votos!
anastrophe

3

'' 'Este código funciona para mim, e é tão simples quanto isso.

Aqui, peguei o valor de ip e estou tentando combiná-lo com regex.

ip="25.255.45.67"    

op=re.match('(\d+).(\d+).(\d+).(\d+)',ip)

if ((int(op.group(1))<=255) and (int(op.group(2))<=255) and int(op.group(3))<=255) and (int(op.group(4))<=255)):

print("valid ip")

else:

print("Not valid")

A condição acima verifica se o valor excede 255 para todos os 4 octetos, então não é válido. Mas antes de aplicar a condição, temos que convertê-los em inteiros, pois o valor está em uma string.

o grupo (0) imprime a saída combinada, enquanto o grupo (1) imprime o primeiro valor correspondido e aqui é "25" e assim por diante. '' '


Bem-vindo ao StackOverflow. Se você pudesse falar por que sua resposta deve resolver o problema do OP, seria ótimo. Respostas apenas em código geralmente são respostas ruins, pois não ajudam outros desenvolvedores a entender o que fizeram de errado.
Davide Vitali

Use recuo adequado em seu código para torná-lo legível para os usuários
Syed Mehtab Hassan


2

Para números de 0 a 255, eu uso este regex:

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

O regex acima corresponderá ao número inteiro de 0 a 255, mas não corresponderá a 256.

Portanto, para IPv4, uso este regex:

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

É nesta estrutura: ^(N)((\.(N)){3})$onde N é a regex usada para corresponder ao número de 0 a 255.
Esta regex irá corresponder ao IP como abaixo:

0.0.0.0
192.168.1.2

mas não aqueles abaixo:

10.1.0.256
1.2.3.
127.0.1-2.3

Para IPv4 CIDR (roteamento entre domínios sem classes), uso este regex:

^(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})\/(([0-9])|([12][0-9])|(3[0-2]))$

É nesta estrutura: ^(N)((\.(N)){3})\/M$onde N é a regex usada para corresponder ao número de 0 a 255 e M é a regex usada para corresponder ao número de 0 a 32.
Esta regex corresponderá ao CIDR como abaixo:

0.0.0.0/0
192.168.1.2/32

mas não aqueles abaixo:

10.1.0.256/16
1.2.3./24
127.0.0.1/33

E para uma lista de CIDR IPv4 como "10.0.0.0/16", "192.168.1.1/32"eu uso esta regex:

^("(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})\/(([0-9])|([12][0-9])|(3[0-2]))")((,([ ]*)("(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})\/(([0-9])|([12][0-9])|(3[0-2]))"))*)$

É nesta estrutura: ^(“C”)((,([ ]*)(“C”))*)$onde C é a regex usada para corresponder ao CIDR (como 0.0.0.0/0).
Este regex corresponderá à lista de CIDR como abaixo:

“10.0.0.0/16”,”192.168.1.2/32”, “1.2.3.4/32”

mas não aqueles abaixo:

“10.0.0.0/16” 192.168.1.2/32 “1.2.3.4/32”

Talvez fique mais curto, mas para mim é fácil de entender tão bem por mim.

Espero que ajude!


Bem-vindo ao SO, agradecemos sua contribuição! Você poderia elaborar um pouco sobre o que as diferentes regexs estão fazendo (em particular a última)?
B - rian de

1

Consegui construir um regex a partir de todas as outras respostas.

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

De acordo com o padrão Ethernet IEEE 802.x, a validação de IP é a faixa de IP 0.xxx >>> não deve ser permitida - IP inválido. # 1.O intervalo de IP começa de 1.xxx a 126.xxx >>>> pode ser configurado. # 2.Faixa IP 127.xxx >>>> não deve ser permitida - IP inválido. # 3.Faixa IP 128.xxx a 223.xxx >> pode ser configurada. a melhor maneira de lidar é sugerida a seguir: ^ (22 [0-3] | 2 [0-1] [0-9] | [1] [0-9] [0-9]? | [1-9 ] [0-9] | [1-9]) \. (25 [0-5] | 2 [0-4] [0-9] | [01]? [0-9] [0-9]? ) \. (25 [0-5] | 2 [0-4] [0-9] | [01]? [0-9] [0-9]?) \. (25 [0-4] | 2 [0-4] [0-9] | [01]? [0-9] [0-9]?) $
Yogesh Aggarwal

1

Com máscara de sub-rede:

^$|([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\
.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\
.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\
.([01]?\\d\\d?|2[0-4]\\d|25[0-5])
((/([01]?\\d\\d?|2[0-4]\\d|25[0-5]))?)$

1
(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))\.){3}(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2})))

Teste para encontrar correspondências no texto, https://regex101.com/r/9CcMEN/2

A seguir estão as regras que definem as combinações válidas em cada número de um endereço IP:

  • Qualquer número de um ou dois dígitos.
  • Qualquer número de três dígitos começando com 1.

  • Qualquer número de três dígitos começando com 2se o segundo dígito for 0 até 4.

  • Qualquer número de três dígitos começando com 25se o terceiro dígito for 0 até 5.

Vamos começar com (((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))\.)um conjunto de quatro subexpressões aninhadas, e vamos examiná-las na ordem inversa. (\d{1,2})corresponde a qualquer número ou números de um ou dois dígitos 0por meio de 99. (1\d{2})corresponde a qualquer número de três dígitos começando com 1( 1seguido por quaisquer dois dígitos) ou números 100até 199. (2[0-4]\d)corresponde a números 200por meio 249. (25[0-5])corresponde a números 250por meio 255. Cada uma dessas subexpressões está incluída em outra subexpressão com um |entre cada uma (de modo que uma das quatro subexpressões deve corresponder, não todas). Depois que o intervalo de números \.coincide ) é colocado em outra subexpressão e repetido três vezes usando. , e então toda a série (todas as opções de número\.{3}. Finalmente, o intervalo de números é repetido (desta vez sem o final\.) para corresponder ao número do endereço IP final. Ao restringir cada um dos quatro números a valores entre 0e 255, esse padrão pode realmente corresponder a endereços IP válidos e rejeitar endereços inválidos.

Trecho de: Ben Forta. “Aprendendo Expressões Regulares.”


Se nem um personagem é procurado no início do endereço de IP nem no final, ^e $metacharacters deve ser usado, respectivamente.

^(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))\.){3}(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2})))$

Teste para encontrar correspondências no texto, https://regex101.com/r/uAP31A/1


1

Tentei torná-lo um pouco mais simples e curto.

^(([01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}([01]?\d{1,2}|2[0-4]\d|25[0-5])$

Se você estiver procurando por java / kotlin:

^(([01]?\\d{1,2}|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d{1,2}|2[0-4]\\d|25[0-5])$

Se alguém quiser saber como funciona fica aqui a explicação. É realmente tão simples. Experimente: p:

 1. ^.....$: '^' is the starting and '$' is the ending.

 2. (): These are called a group. You can think of like "if" condition groups.

 3. |: 'Or' condition - as same as most of the programming languages.

 4. [01]?\d{1,2}: '[01]' indicates one of the number between 0 and 1. '?' means '[01]' is optional. '\d' is for any digit between 0-9 and '{1,2}' indicates the length can be between 1 and 2. So here the number can be 0-199.

 5. 2[0-4]\d: '2' is just plain 2. '[0-4]' means a number between 0 to 4. '\d' is for any digit between 0-9. So here the number can be 200-249.

 6. 25[0-5]: '25' is just plain 25. '[0-5]' means a number between 0 to 5. So here the number can be 250-255.

 7. \.: It's just plan '.'(dot) for separating the numbers.

 8. {3}: It means the exact 3 repetition of the previous group inside '()'.

 9. ([01]?\d{1,2}|2[0-4]\d|25[0-5]): Totally same as point 2-6

Matematicamente, é como:

(0-199 OR 200-249 OR 250-255).{Repeat exactly 3 times}(0-199 OR 200-249 OR 250-255)

Então, como você pode ver normalmente, esse é o padrão para os endereços IP. Espero que ajude a entender um pouco a Expressão Regular. : p


1

Tentei torná-lo um pouco mais simples e curto.

^ (([01]? \ D {1,2} | 2 [0-4] \ d | 25 [0-5]).) {3} ([01]? \ D {1,2} | 2 [0-4] \ d | 25 [0-5]) $

Se você estiver procurando por java / kotlin:

^ (([01]? \ D {1,2} | 2 [0-4] \ d | 25 [0-5]) \.) {3} ([01]? \ D {1,2} | 2 [0-4] \ d | 25 [0-5]) $

Se alguém quiser saber como funciona fica aqui a explicação. É realmente tão simples. Experimente: p:

 1. ^.....$: '^' is the starting and '$' is the ending.

 2. (): These are called a group. You can think of like "if" condition groups.

 3. |: 'Or' condition - as same as most of the programming languages.

 4. [01]?\d{1,2}: '[01]' indicates one of the number between 0 and 1. '?' means '[01]' is optional. '\d' is for any digit between 0-9 and '{1,2}' indicates the length can be between 1 and 2. So here the number can be 0-199.

 5. 2[0-4]\d: '2' is just plain 2. '[0-4]' means a number between 0 to 4. '\d' is for any digit between 0-9. So here the number can be 200-249.

 6. 25[0-5]: '25' is just plain 25. '[0-5]' means a number between 0 to 5. So here the number can be 250-255.

 7. \.: It's just plan '.'(dot) for separating the numbers.

 8. {3}: It means the exact 3 repetition of the previous group inside '()'.

 9. ([01]?\d{1,2}|2[0-4]\d|25[0-5]): Totally same as point 2-6

Matematicamente, é como:

(0-199 OR 200-249 OR 250-255).{Repeat exactly 3 times}(0-199 OR 200-249 OR 250-255)

Então, como você pode ver normalmente, esse é o padrão para os endereços IP. Espero que ajude a entender um pouco a Expressão Regular. : p


0
    const char*ipv4_regexp = "\\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
    "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
    "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
    "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b";

Eu adaptei a expressão regular tirada da biblioteca JGsoft RegexBuddy para a linguagem C (regcomp / regexec) e descobri que funciona, mas há um pequeno problema em alguns sistemas operacionais como o Linux. Essa expressão regular aceita endereço ipv4 como 192.168.100.009, onde 009 no Linux é considerado um valor octal, então o endereço não é o que você pensava. Mudei essa expressão regular da seguinte maneira:

    const char* ipv4_regex = "\\b(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
           "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
           "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
           "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\b";

usar aquela expressão regular agora 192.168.100.009 não é um endereço ipv4 válido, enquanto 192.168.100.9 está ok.

Eu modifiquei uma expressão regular para o endereço multicast também e é a seguinte:

    const char* mcast_ipv4_regex = "\\b(22[4-9]|23[0-9])\\."
                        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
                        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]?)\\."
                        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\b";

Acho que você deve adaptar a expressão regular à linguagem que está usando para desenvolver seu aplicativo

Eu coloquei um exemplo em java:

    package utility;

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;

    public class NetworkUtility {

        private static String ipv4RegExp = "\\b(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d?)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d?)\\b";

        private static String ipv4MulticastRegExp = "2(?:2[4-9]|3\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d?|0)){3}";

        public NetworkUtility() {

        }

        public static boolean isIpv4Address(String address) {
            Pattern pattern = Pattern.compile(ipv4RegExp);
            Matcher matcher = pattern.matcher(address);

            return matcher.matches();
        }

        public static boolean isIpv4MulticastAddress(String address) {
             Pattern pattern = Pattern.compile(ipv4MulticastRegExp);
             Matcher matcher = pattern.matcher(address);

             return matcher.matches();
        }
    }

0
-bash-3.2$ echo "191.191.191.39" | egrep 
  '(^|[^0-9])((2([6-9]|5[0-5]?|[0-4][0-9]?)?|1([0-9][0-9]?)?|[3-9][0-9]?|0)\.{3}
     (2([6-9]|5[0-5]?|[0-4][0-9]?)?|1([0-9][0-9]?)?|[3-9][0-9]?|0)($|[^0-9])'

>> 191.191.191.39

(Este é um DFA que corresponde a todo o espaço addr (incluindo broadcasts, etc.) e nada mais.


0

Acho que esse é o mais curto.

^(([01]?\d\d?|2[0-4]\d|25[0-5]).){3}([01]?\d\d?|2[0-4]\d|25[0-5])$

0

Achei este exemplo muito útil, além disso, permite diferentes notações do ipv4.

exemplo de código usando python:

    def is_valid_ipv4(ip4):
    """Validates IPv4 addresses.
    """
    import re
    pattern = re.compile(r"""
        ^
        (?:
          # Dotted variants:
          (?:
            # Decimal 1-255 (no leading 0's)
            [3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
          |
            0x0*[0-9a-f]{1,2}  # Hexadecimal 0x0 - 0xFF (possible leading 0's)
          |
            0+[1-3]?[0-7]{0,2} # Octal 0 - 0377 (possible leading 0's)
          )
          (?:                  # Repeat 0-3 times, separated by a dot
            \.
            (?:
              [3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
            |
              0x0*[0-9a-f]{1,2}
            |
              0+[1-3]?[0-7]{0,2}
            )
          ){0,3}
        |
          0x0*[0-9a-f]{1,8}    # Hexadecimal notation, 0x0 - 0xffffffff
        |
          0+[0-3]?[0-7]{0,10}  # Octal notation, 0 - 037777777777
        |
          # Decimal notation, 1-4294967295:
          429496729[0-5]|42949672[0-8]\d|4294967[01]\d\d|429496[0-6]\d{3}|
          42949[0-5]\d{4}|4294[0-8]\d{5}|429[0-3]\d{6}|42[0-8]\d{7}|
          4[01]\d{8}|[1-3]\d{0,9}|[4-9]\d{0,8}
        )
        $
    """, re.VERBOSE | re.IGNORECASE)
    return pattern.match(ip4) <> None

0
((\.|^)(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0$)){4}

Este regex não aceitará 08.8.8.8 ou 8.08.8.8 ou 8.8.08.8 ou 8.8.8.08


este perde por exemplo 127.0.0.1 e 0.0.0.0
AnneB

^ ((\. | ^) (25 [0-5] | 2 [0-4] [0-9] | 1 [0-9] [0-9] | [1-9] [0-9] ? | [0-9]? | 0)) ((\. | ^) (25 [0-5] | 2 [0-4] [0-9] | 1 [0-9] [0-9] | [1-9] [0-9]? | 0)) {2}. ((25 [0-5] | 2 [0-4] [0-9] | 1 [0-9] [0- 9] | [1-9] [0-9]? | 0) $)
sudistack

1
É correto rejeitar zeros à esquerda, de acordo com as especificações.
John Haugeland,

0

Encontra endereços de IP válidos, desde que o IP envolva qualquer caractere diferente de dígitos (antes ou antes do IP). 4 Referências anteriores criadas: $ + {primeiro}. $ + {Segundo}. $ + {Terceiro}. $ + {Adiante}

Find String:
#any valid IP address
(?<IP>(?<![\d])(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))
#only valid private IP address RFC1918
(?<IP>(?<![\d])(:?(:?(?<first>10)[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5])))|(:?(?<first>172)[\.](?<second>(:?1[6-9])|(:?2[0-9])|(:?3[0-1])))|(:?(?<first>192)[\.](?<second>168)))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))

Notepad++ Replace String Option 1: Replaces the whole IP (NO Change):
$+{IP}

Notepad++ Replace String Option 2: Replaces the whole IP octect by octect (NO Change)
$+{first}.$+{second}.$+{third}.$+{forth}

Notepad++ Replace String Option 3: Replaces the whole IP octect by octect (replace 3rd octect value with 0)
$+{first}.$+{second}.0.$+{forth}
NOTE: The above will match any valid IP including 255.255.255.255 for example and change it to 255.255.0.255 which is wrong and not very useful of course.

Substituindo parte de cada octeto por um valor real, no entanto, você pode construir seu próprio localizar e substituir, o que é realmente útil para corrigir IPs em arquivos de texto:

for example replace the first octect group of the original Find regex above:
(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))
with
(?<first>10)

and
(?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))
with
(?<second>216)
and you are now matching addresses starting with first octect 192 only

Find on notepad++:
(?<IP>(?<![\d])(?<first>10)[\.](?<second>216)[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))

Você ainda pode executar Substituir usando grupos de referência inversa exatamente da mesma maneira que antes.

Você pode ter uma ideia de como o acima foi combinado abaixo:

cat ipv4_validation_test.txt
Full Match:
0.0.0.1
12.108.1.34
192.168.1.1
10.249.24.212
10.216.1.212
192.168.1.255
255.255.255.255
0.0.0.0


Partial Match (IP Extraction from line)
30.168.1.0.1
-1.2.3.4
sfds10.216.24.23kgfd
da11.15.112.255adfdsfds
sfds10.216.24.23kgfd


NO Match
1.1.1.01
3...3
127.1.
192.168.1..
192.168.1.256
da11.15.112.2554adfdsfds
da311.15.112.255adfdsfds

Usando o grep, você pode ver os resultados abaixo:

From grep:
grep -oP '(?<IP>(?<![\d])(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))' ipv4_validation_test.txt
0.0.0.1
12.108.1.34
192.168.1.1
10.249.24.212
10.216.1.212
192.168.1.255
255.255.255.255
0.0.0.0
30.168.1.0
1.2.3.4
10.216.24.23
11.15.112.255
10.216.24.23


grep -P '(?<IP>(?<![\d])(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))' ipv4_validation_test.txt
0.0.0.1
12.108.1.34
192.168.1.1
10.249.24.212
10.216.1.212
192.168.1.255
255.255.255.255
0.0.0.0
30.168.1.0.1
-1.2.3.4
sfds10.216.24.23kgfd
da11.15.112.255adfdsfds
sfds10.216.24.23kgfd


#matching ip addresses starting with 10.216
grep -oP '(?<IP>(?<![\d])(?<first>10)[\.](?<second>216)[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))' ipv4_validation_test.txt
10.216.1.212
10.216.24.23
10.216.24.23

0

O endereço IPv4 é uma coisa muito complicada.

Nota : Indentação e forro são apenas para fins ilustrativos e não existem no RegEx real.

\b(
  ((
    (2(5[0-5]|[0-4][0-9])|1[0-9]{2}|[1-9]?[0-9])
  |
    0[Xx]0*[0-9A-Fa-f]{1,2}
  |
    0+[1-3]?[0-9]{1,2}
  )\.){1,3}
  (
    (2(5[0-5]|[0-4][0-9])|1[0-9]{2}|[1-9]?[0-9])
  |
    0[Xx]0*[0-9A-Fa-f]{1,2}
  |
    0+[1-3]?[0-9]{1,2}
  )
|
  (
    [1-3][0-9]{1,9}
  |
    [1-9][0-9]{,8}
  |
    (4([0-1][0-9]{8}
      |2([0-8][0-9]{7}
        |9([0-3][0-9]{6}
          |4([0-8][0-9]{5}
            |9([0-5][0-9]{4}
              |6([0-6][0-9]{3}
                |7([0-1][0-9]{2}
                  |2([0-8][0-9]{1}
                    |9([0-5]
    ))))))))))
  )
|
  0[Xx]0*[0-9A-Fa-f]{1,8}
|
  0+[1-3]?[0-7]{,10}
)\b

Esses endereços IPv4 são validados pelo RegEx acima.

127.0.0.1
2130706433
0x7F000001
017700000001
0x7F.0.0.01 # Mixed hex/dec/oct
000000000017700000001 # Have as many leading zeros as you want
0x0000000000007F000001 # Same as above
127.1
127.0.1

Estes são rejeitados.

256.0.0.1
192.168.1.099 # 099 is not a valid number
4294967296 # UINT32_MAX + 1
0x100000000
020000000000

0

^((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]?))$


Acima será regex para o endereço IP como: 221.234.000.112 também para 221.234.0.112, 221.24.03.112, 221.234.0.1


Você pode imaginar todos os tipos de endereços acima


0

Eu usaria PCRE e a definepalavra-chave:

/^
 ((?&byte))\.((?&byte))\.((?&byte))\.((?&byte))$
 (?(DEFINE)
     (?<byte>25[0-5]|2[0-4]\d|[01]?\d\d?))
/gmx

Demo: https://regex101.com/r/IB7j48/2

A razão disso é evitar repetir o (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)padrão quatro vezes. Outras soluções, como a abaixo, funcionam bem, mas não capturam cada grupo como seria solicitado por muitos.

/^((\d+?)(\.|$)){4}/ 

A única outra maneira de ter 4 grupos de captura é repetir o padrão quatro vezes:

/^(?<one>\d+)\.(?<two>\d+)\.(?<three>\d+)\.(?<four>\d+)$/

Capturar um ipv4 em perl é, portanto, muito fácil

$ echo "Hey this is my IP address 138.131.254.8, bye!" | \
  perl -ne 'print "[$1, $2, $3, $4]" if \
    /\b((?&byte))\.((?&byte))\.((?&byte))\.((?&byte))
     (?(DEFINE)
        \b(?<byte>25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))
    /x'

[138, 131, 254, 8]

0

A expressão regular IPv4 mais precisa, direta e compacta que posso imaginar é

^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$

Mas e quanto ao desempenho / eficiência de ... Desculpe, não sei, quem se importa?


0

Experimente isto:

\b(([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\.([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\.([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\.(2[0-5][0-5]|1[0-9][0-9]|[1-9][0-9]|[1-9]))\b

0
ip address can be from 0.0.0.0 to 255.255.255.255

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

(0|1)?[0-9][0-9]? - checking value from 0 to 199
2[0-4][0-9]- checking value from 200 to 249
25[0-5]- checking value from 250 to 255
[.] --> represent verify . character 
{3} --> will match exactly 3
$ --> end of string

0

A seguir está a expressão regex para validar o endereço IP.

^((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]?)$

0

Jeito fácil

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

Demo

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.