Estou tendo problemas para escrever uma expressão regular que corresponda a endereços IPv6 válidos, incluindo aqueles em sua forma compactada (com ::
ou zeros à esquerda omitidos de cada par de bytes).
Alguém pode sugerir uma expressão regular que cumpra o requisito?
Estou pensando em expandir cada par de bytes e combinar o resultado com um regex mais simples.
regex
networking
ipv6
Somente leitura
fonte
fonte
Respostas:
Não consegui que a resposta de @Factor Mystic funcionasse com expressões regulares POSIX, então escrevi uma que funciona com expressões regulares POSIX e expressões regulares PERL.
Deve corresponder a:
Expressão regular IPv6:
Para facilitar a leitura, o seguinte é a expressão regular acima dividida em pontos OR principais em linhas separadas:
Para facilitar a compreensão do acima, o seguinte código "pseudo" replica o acima:
Eu postei um script no GitHub que testa a expressão regular: https://gist.github.com/syzdek/6086792
fonte
127.000.000.001
fe80
onde deveria ser algo[fF][eE]80
e umffff
que deveria ser algo como[fF]{4}
O seguinte irá validar os endereços IPv4, IPv6 (completo e compactado) e IPv6v4 (completo e compactado):
fonte
Parece que você está usando Python. Nesse caso, você pode usar algo assim:
Não acho que você precise ter IPv6 compilado em Python para obter
inet_pton
, que também pode analisar endereços IPv4 se você passarsocket.AF_INET
como o primeiro parâmetro. Nota: isso pode não funcionar em sistemas não-Unix.fonte
except
cláusula. Caso contrário,except
irá capturar tudo e pode mascarar erros não relacionados. O tipo aqui deve sersocket.error
.De " IPv6 regex ":
fonte
Eu teria que apoiar fortemente a resposta de Frank Krueger .
Embora você diga que precisa de uma expressão regular para corresponder a um endereço IPv6, estou assumindo que o que você realmente precisa é ser capaz de verificar se uma determinada string é um endereço IPv6 válido. Há uma distinção sutil, mas importante aqui.
Há mais de uma maneira de verificar se uma determinada string é um endereço IPv6 válido e a correspondência de expressão regular é apenas uma solução.
Use uma biblioteca existente, se puder. A biblioteca terá menos bugs e seu uso resultará em menos código para você manter.
A expressão regular sugerida pelo Factor Mystic é longa e complexa. Provavelmente funciona, mas você também deve considerar como lidaria se ele falhasse inesperadamente. O que estou tentando enfatizar aqui é que, se você não puder formar uma expressão regular exigida, não será capaz de depurá-la facilmente.
Se você não tiver uma biblioteca adequada, pode ser melhor escrever sua própria rotina de validação IPv6 que não dependa de expressões regulares. Se você o escrever, você o compreenderá e, se compreender, poderá adicionar comentários para explicá-lo, de modo que outros também possam entendê-lo e, posteriormente, mantê-lo.
Aja com cuidado ao usar uma expressão regular cuja funcionalidade você não pode explicar a outra pessoa.
fonte
return ex1.match(S) && ! ex2.match(S)
).Não sou um especialista em IPv6, mas acho que você pode obter um resultado muito bom mais facilmente com este:
para responder "é um ipv6 válido" parece ok para mim. Para quebrar em partes ... esqueça. Omiti o não especificado (: :), uma vez que não adianta ter "endereço não especificado" em meu banco de dados.
o início:
^([0-9A-Fa-f]{0,4}:){2,7}
<- corresponde à parte compressível, podemos traduzir isso como: entre 2 e 7 dois pontos que podem ter um número heaxadecimal entre eles.seguido por:
[0-9A-Fa-f]{1,4}$
<- um número hexadecimal (0 inicial omitido) OU((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}
<- um endereço Ipv4fonte
start() = 0, end() = 3 group(0) = "::1" group(1) = ":" group(2) = "1" group(3) = "null" group(4) = "null" group(5) = "null"
Isso captura o loopback (:: 1) também e os endereços ipv6. mudou {} para + e colocou: dentro do primeiro colchete.
testado com ifconfig -a output http://regexr.com/
A opção o terminal Unix ou Mac OSx retorna apenas a saída correspondente (ipv6) incluindo :: 1
Obtenha todos os endereços IP (IPv4 OU IPv6) e imprima a correspondência no termo unix OSx
fonte
ip a | grep -Po '[\w:]+:+[\w:]+'
Esta expressão regular corresponderá a endereços IPv6 e IPv4 válidos de acordo com a implementação GNU C ++ de regex com o modo REGULAR EXTENDED usado:
fonte
Cuidado! Em Java, o uso de InetAddress e classes relacionadas (Inet4Address, Inet6Address, URL) pode envolver tráfego de rede! Por exemplo, resolução de DNS (URL.equals, InetAddress da string!). Esta chamada pode demorar e está bloqueando!
Para IPv6, tenho algo assim. É claro que isso não lida com os detalhes muito sutis do IPv6, como os índices de zona são permitidos apenas em algumas classes de endereços IPv6. E este regex não foi escrito para captura de grupo, é apenas um tipo de regexp que "combina".
S
- segmento IPv6 =[0-9a-f]{1,4}
I
- IPv4 =(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})
Esquema (a primeira parte corresponde aos endereços IPv6 com o sufixo IPv4, a segunda parte corresponde aos endereços IPv6, último patrão do índice da zona):
E aqui o pode regex (não diferencia maiúsculas de minúsculas, envolve o que for necessário, como início / fim de linha, etc.):
fonte
O regex a seguir é apenas para IPv6. O grupo 1 corresponde ao IP.
fonte
Um regex simples que corresponderá, mas eu não recomendaria para validação de qualquer tipo é este:
Observe que isso corresponde à compressão em qualquer lugar do endereço, embora não corresponda ao endereço de loopback :: 1. Acho este um meio-termo razoável para manter a regex simples.
Eu uso isso com sucesso nas regras de seleção inteligente de iTerm2 para endereços IPv6 de quatro cliques.
fonte
A-F
, nãoA-Z
! Observe também que você está excluindo a notação com quatro pontos.Se você usar Perl, tente Net :: IPv6Addr
NetAddr :: IP
Validate :: IP
fonte
No Scala, use os conhecidos validadores Apache Commons.
http://mvnrepository.com/artifact/commons-validator/commons-validator/1.4.1
Seguindo os testes do método
ip(ip: String)
:fonte
1200:0000:AB00:1234:0000:2552:7777:1313
é um formato válido para um endereço IPv6, mas não é um endereço IPv6 válido conforme o método de teste retorna. Aposto que ele pensa que241.54.113.65
é um endereço IPv4 válido.Olhando para os padrões incluídos nas outras respostas, há uma série de bons padrões que podem ser melhorados referenciando grupos e utilizando antecipações. Aqui está um exemplo de um padrão que é auto-referenciado que eu utilizaria em PHP se eu tivesse que:
Nota: o PHP tem um filtro embutido para isso, que seria uma solução melhor do que este padrão.
Análise Regex101
fonte
Eu gerei o seguinte usando python e funcione com o módulo re. As declarações antecipadas garantem que o número correto de pontos ou dois pontos apareça no endereço. Não suporta IPv4 na notação IPv6.
fonte
Regexes para ipv6 podem ficar realmente complicados quando você considera endereços com ipv4 incorporado e endereços que são compactados, como você pode ver em algumas dessas respostas.
A biblioteca Java IPAddress de código aberto validará todas as representações padrão de IPv6 e IPv4 e também suporta comprimento de prefixo (e validação de tal). Isenção de responsabilidade: eu sou o gerente de projeto dessa biblioteca.
Exemplo de código:
fonte
Em Java, você pode usar a classe de biblioteca
sun.net.util.IPAddressUtil
:fonte
É difícil encontrar uma expressão regular que funcione para todos os casos IPv6. Eles geralmente são difíceis de manter, não são facilmente legíveis e podem causar problemas de desempenho. Portanto, quero compartilhar uma solução alternativa que desenvolvi: Expressão regular (RegEx) para IPv6 separado do IPv4
Agora você pode perguntar: "Este método encontra apenas IPv6, como posso encontrar IPv6 em um texto ou arquivo?" Aqui estão os métodos para esse problema.
Observação : se você não quiser usar a classe IPAddress no .NET, também pode substituí-la pelo meu método . Ele também cobre o IPv4 mapeado e casos especiais, enquanto o IPAddress não cobre.
fonte
InetAddressUtils
tem todos os padrões definidos. Acabei usando o padrão diretamente e estou colando aqui para referência:fonte
Usando Ruby? Experimente isto:
fonte
Dependendo de suas necessidades, uma aproximação como:
pode ser o suficiente (como com grepping de arquivo de log simples, por exemplo.)
fonte
Para usuários do PHP 5.2+
filter_var
funciona muito bem.Eu sei que isso não responde à pergunta original (especificamente uma solução regex), mas eu postei isso na esperança de que possa ajudar alguém no futuro.
fonte
Isso funcionará para IPv4 e IPv6:
fonte
::
. por exemplo2404:6800::4003:c02::8a
Aqui está o que eu criei, usando um pouco de lookahead e grupos nomeados. É claro que é apenas IPv6, mas não deve interferir com padrões adicionais se você quiser adicionar IPv4:
fonte
Você pode usar as ferramentas do shell ipextract que fiz para esse propósito. Eles são baseados em regexp e grep.
Uso:
fonte
Apenas combinando os locais de uma origem com colchetes incluídos. Eu sei que não é tão abrangente, mas em javascript os outros tinham problemas de rastreamento principalmente de não funcionar, então isso parece me dar o que eu precisava no momento. AF capitais extras também não são necessários.
A versão de Jinnko é simplificada e melhor eu vejo.
fonte
Como afirmado acima, outra maneira de obter um analisador de validação de representação textual IPv6 é usar programação. Aqui está um que é totalmente compatível com RFC-4291 e RFC-5952. Escrevi este código em ANSI C (funciona com GCC, passei nos testes do Linux - funciona com clang, passei nos testes do FreeBSD). Portanto, ele depende apenas da biblioteca padrão ANSI C, portanto, pode ser compilado em qualquer lugar (eu o usei para análise IPv6 dentro de um módulo de kernel com FreeBSD).
fonte
Experimente este pequeno one-liner. Deve corresponder apenas a endereços IPv6 descompactados / compactados válidos (sem híbridos de IPv4)
fonte
O regex permite o uso de zeros à esquerda nas partes IPv4.
Algumas distros Unix e Mac convertem esses segmentos em octais.
Eu sugiro usar
25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d
como segmento IPv4.fonte
Se você quiser apenas IP-s normais (sem barras), aqui:
Eu o uso para meu marcador de sintaxe no aplicativo editor de arquivos hosts. Funciona como charme.
fonte