Expressão regular que corresponde a todos os endereços IPv6 de formato válido
À primeira vista, admito que esta pergunta se parece com uma duplicata desta e de qualquer outra relacionada a ela:
Expressão regular que corresponde a endereços IPv6 válidos
Na verdade, essa pergunta tem uma resposta que quase responde à minha pergunta,mas não totalmente.
O código dessa pergunta com a qual tenho problemas, mas tive mais sucesso, é mostrado abaixo:
private string RemoveIPv6(string sInput)
{
string pattern = @"(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))";
//That is one looooong regex! From: https://stackoverflow.com/a/17871737/3472690
//if (IsCompressedIPv6(sInput))
// sInput = UncompressIPv6(sInput);
string output = Regex.Replace(sInput, pattern, "");
if (output.Contains("Addresses"))
output = output.Substring(0, "Addresses: ".Length);
return output;
}
Os problemas que tive com o padrão regex, conforme fornecido nesta resposta,Resposta de David M. Syzdek, é que ele não corresponde e remove a forma completa dos endereços IPv6 que estou jogando nele.
Estou usando o padrão regex para substituir principalmente endereços IPv6 em cadeias de caracteres com espaços em branco ou valor nulo.
Por exemplo,
Addresses: 2404:6800:4003:c02::8a
Assim como...
Addresses: 2404:6800:4003:804::200e
E finalmente...
Addresses: 2001:4998:c:a06::2:4008
Todos eles não são totalmente correspondidos pelo regex ou não foram completamente correspondidos.
A regex retornará as partes restantes da string, como mostrado abaixo:
Addresses: 8a
Addresses: 200e
Addresses: 2:4008
Como pode ser visto, ele deixou restos dos endereços IPv6, difíceis de detectar e remover, devido aos formatos variados em que os remanescentes assumem. Abaixo está o padrão regex por si só para uma melhor análise:
(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))
Portanto,minha pergunta é, como esse padrão de regex pode ser corrigido para corresponder e, portanto, permitir a remoção completa de qualquer endereço IPv6 de uma sequência que não contém apenas o (s) endereço (s) IPv6?
alternativamente, como o snippet de código que forneci acima pode ser corrigido para fornecer o resultado necessário?
Para quem pode estar se perguntando, estou recebendo a string dos comandos StandardOutput dos nslookup, e os endereços IPv6 sempre serão diferentes. Para os exemplos acima, obtive esses endereços IPv6 em "google.com" e "yahoo.com".
Não estou usando a função interna para resolver entradas DNS por um bom motivo, o que acho que não importa no momento; portanto, estou usando o nslookup.
Quanto ao código que está chamando essa função, se necessário, é o seguinte: (Ele também é outra função / método, ou melhor, parte de um)
string output = "";
string garbagecan = "";
string tempRead = "";
string lastRead = "";
using (StreamReader reader = nslookup.StandardOutput)
{
while (reader.Peek() != -1)
{
if (LinesRead > 3)
{
tempRead = reader.ReadLine();
tempRead = RemoveIPv6(tempRead);
if (tempRead.Contains("Addresses"))
output += tempRead;
else if (lastRead.Contains("Addresses"))
output += tempRead.Trim() + Environment.NewLine;
else
output += tempRead + Environment.NewLine;
lastRead = tempRead;
}
else
garbagecan = reader.ReadLine();
LinesRead++;
}
}
return output;
O regex corrigido deve permitir apenas a remoção de endereços IPv6 e deixar os endereços IPv4 intocados.A cadeia que será passada para o regex não conterá o (s) endereço (s) IPv6 sozinho e quase sempre conterá outros detalhes e, como tal, é imprevisível em qual índice os endereços aparecerão. O regex também está ignorando todos os outros endereços IPv6 após os primeiros endereços IPv6, por algum motivo, deve-se notar.
Desculpas se houver algum detalhe ausente, tentarei incluí-lo quando alertado. Eu também preferiria exemplos de código de trabalho, se possível, pois tenho quase zero conhecimento sobre regex.