匹配所有有效格式 IPv6 地址的正则表达式
Regular expression that matches all valid format IPv6 addresses
乍一看,我承认这个问题看起来像是这个问题以及任何其他相关问题的重复:
Regular expression that matches valid IPv6 addresses
这个问题实际上有一个几乎回答了我的问题的答案,但不完全。
我遇到问题但最成功的那个问题的代码如下所示:
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:
//if (IsCompressedIPv6(sInput))
// sInput = UncompressIPv6(sInput);
string output = Regex.Replace(sInput, pattern, "");
if (output.Contains("Addresses"))
output = output.Substring(0, "Addresses: ".Length);
return output;
}
我在这个答案 David M. Syzdek's Answer 中提供的正则表达式模式遇到的问题是它不匹配并删除了我抛给它的 IPv6 地址的完整形式。
我主要使用正则表达式模式将字符串中的 IPv6 地址替换为空白或空值。
例如,
Addresses: 2404:6800:4003:c02::8a
以及...
Addresses: 2404:6800:4003:804::200e
最后...
Addresses: 2001:4998:c:a06::2:4008
全部都没有被正则表达式完全匹配,或者完全匹配失败。
正则表达式 return 字符串的其余部分如下所示:
Addresses: 8a
Addresses: 200e
Addresses: 2:4008
可以看出,它留下了 IPv6 地址的残余,由于残余采用的格式各不相同,因此很难检测和删除。为了更好地分析,下面是正则表达式模式本身:
(([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]))
因此,我的问题是,如何更正此正则表达式模式以便匹配,从而允许从不匹配的字符串中完全删除任何 IPv6 地址是否仅包含 IPv6 地址本身?
或者,如何更正我上面提供的代码片段以提供所需的结果?
对于那些可能想知道的人,我从 nslookup 命令的 StandardOutput 中获取字符串,而 IPv6 地址总是不同的。对于上面的示例,我从 "google.com" 和 "yahoo.com".
获得了这些 IPv6 地址
我没有使用内置函数来解析 DNS 条目是有充分理由的,我认为目前这并不重要,因此我正在使用 nslookup。
至于调用该函数的代码,如果需要的话,如下:(它本身也是另一个function/method,或者更确切地说是一个的一部分)
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;
更正后的正则表达式应该只允许删除 IPv6 地址,而 IPv4 地址保持不变。 将传递给正则表达式的字符串不会单独包含 IPv6 地址,并且几乎总是包含其他详细信息,因此,无法预测地址将出现在哪个索引处。 出于某种原因,正则表达式也会在第一个出现的 IPv6 地址之后跳过所有其他 IPv6 地址,应该注意。
抱歉,如果有任何遗漏的细节,我会尽力将它们包含在提醒中。如果可能的话,我也更喜欢工作代码示例,因为我对正则表达式的了解几乎为零。
(?:^|(?<=\s))(([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]))(?=\s|$)
使用 lookarounds
您可以强制执行完整匹配而不是 partial
match.See 演示。
(?i)(?:[\da-f]{0,4}:){1,7}(?:(?<ipv4>(?:(?:25[0-5]|2[0-4]\d|1?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|1?\d\d?))|[\da-f]{0,4})
演示:Regex101
乍一看,我承认这个问题看起来像是这个问题以及任何其他相关问题的重复:
Regular expression that matches valid IPv6 addresses
这个问题实际上有一个几乎回答了我的问题的答案,但不完全。
我遇到问题但最成功的那个问题的代码如下所示:
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:
//if (IsCompressedIPv6(sInput))
// sInput = UncompressIPv6(sInput);
string output = Regex.Replace(sInput, pattern, "");
if (output.Contains("Addresses"))
output = output.Substring(0, "Addresses: ".Length);
return output;
}
我在这个答案 David M. Syzdek's Answer 中提供的正则表达式模式遇到的问题是它不匹配并删除了我抛给它的 IPv6 地址的完整形式。
我主要使用正则表达式模式将字符串中的 IPv6 地址替换为空白或空值。
例如,
Addresses: 2404:6800:4003:c02::8a
以及...
Addresses: 2404:6800:4003:804::200e
最后...
Addresses: 2001:4998:c:a06::2:4008
全部都没有被正则表达式完全匹配,或者完全匹配失败。
正则表达式 return 字符串的其余部分如下所示:
Addresses: 8a
Addresses: 200e
Addresses: 2:4008
可以看出,它留下了 IPv6 地址的残余,由于残余采用的格式各不相同,因此很难检测和删除。为了更好地分析,下面是正则表达式模式本身:
(([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]))
因此,我的问题是,如何更正此正则表达式模式以便匹配,从而允许从不匹配的字符串中完全删除任何 IPv6 地址是否仅包含 IPv6 地址本身?
或者,如何更正我上面提供的代码片段以提供所需的结果?
对于那些可能想知道的人,我从 nslookup 命令的 StandardOutput 中获取字符串,而 IPv6 地址总是不同的。对于上面的示例,我从 "google.com" 和 "yahoo.com".
获得了这些 IPv6 地址我没有使用内置函数来解析 DNS 条目是有充分理由的,我认为目前这并不重要,因此我正在使用 nslookup。
至于调用该函数的代码,如果需要的话,如下:(它本身也是另一个function/method,或者更确切地说是一个的一部分)
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;
更正后的正则表达式应该只允许删除 IPv6 地址,而 IPv4 地址保持不变。 将传递给正则表达式的字符串不会单独包含 IPv6 地址,并且几乎总是包含其他详细信息,因此,无法预测地址将出现在哪个索引处。 出于某种原因,正则表达式也会在第一个出现的 IPv6 地址之后跳过所有其他 IPv6 地址,应该注意。
抱歉,如果有任何遗漏的细节,我会尽力将它们包含在提醒中。如果可能的话,我也更喜欢工作代码示例,因为我对正则表达式的了解几乎为零。
(?:^|(?<=\s))(([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]))(?=\s|$)
使用 lookarounds
您可以强制执行完整匹配而不是 partial
match.See 演示。
(?i)(?:[\da-f]{0,4}:){1,7}(?:(?<ipv4>(?:(?:25[0-5]|2[0-4]\d|1?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|1?\d\d?))|[\da-f]{0,4})
演示:Regex101