IP地址的正则表达式

52

我试图使用这个源代码提取wan_ip的值(IP地址):

什么问题?!我确定正则表达式模式是正确的。
String input = @"var product_pic_fn=;var firmware_ver='20.02.024';var wan_ip='92.75.120.206';if (parent.location.href != window.location.href)";
Regex ip = new Regex(@"[\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b");
string[] result = ip.Split(input);

foreach (string bla in result)  
{
  Console.WriteLine(bla);                
}

Console.Read();

4
除了表达方式外,你应该看看Regex.Matches而不是Split吧? - Ani
可能是重复的问题:正则表达式匹配主机名或IP地址? - Daniel DiPaolo
7
这是一个IP地址的格式,通常用于标识计算机或设备在网络中的位置。 - Andrey
1
@Andrey 没关系,它是一个字符串,可以最近使用 ipaddress.TryParse 进行检查。这里的主要目的是获取应该是 IP 的字符串。 - Hi-Angel
异常。从正则表达式字符串中删除第一个[ - Darkgaze
13个回答

55

你的模式开头不应该是 [。此外,你可能想要使用 Matches(...)

尝试如下:

String input = @"var product_pic_fn=;var firmware_ver='20.02.024';var wan_ip='92.75.120.206';if (parent.location.href != window.location.href)";
Regex ip = new Regex(@"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b");
MatchCollection result = ip.Matches(input);
Console.WriteLine(result[0]); 

1
如果@John的建议有效,我会选择那个。如果不行,请尝试@SwDevMan81的代码:首先检查是否有匹配项似乎更安全。我的(快速)建议可能会在没有匹配项时产生错误(我有点C#新手...)。 - Bart Kiers
如果IP地址是192.168.1.15_1,它就无法正常工作。 - Jay
无法处理008.008.008.008这种无效的IPAddress,但是你的模式却接受它。 - Mohammad
4
我从未声称它只会匹配有效的IP地址。使用正则表达式不应该这样做。 - Bart Kiers

49

这是一个非常古老的帖子,你应该使用被接受的解决方案,但要考虑使用正确的正则表达式来匹配IPv4地址:

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

如果你想避免在之前或之后出现特殊字符,你可以使用:

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

2
看起来不错,但是当我使用它时,如果我在有效的IP后附加无效字符,它也会匹配。 - oo_dev
3
你是正确的,正则表达式支持前缀和后缀,我已经编辑了我的回答。 - JPBlanc
\b(...)\b 也许值得添加?顺便说一句,回答很棒。 - Santiago Squarzon

17

试试这个:

 Match match = Regex.Match(input, @"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}");
 if (match.Success)
 {
     Console.WriteLine(match.Value);
 }

它正在处理192.168.1.15_1的情况。+1 - Jay
4
192.168.1.15_1?为什么需要考虑它? - V-SHY

16

如果您只想检查正确的 IP,请使用 IPAddress.TryParse

using System.Net;

bool isIP(string host)
{
    IPAddress ip;
    return IPAddress.TryParse(host, out ip);
}

在Unity中,这会使我得到“123”的真值。ô.O - dasLort

6

我知道这篇文章不是最新的,但是我尝试了几种提出的解决方案,没有一个像我通过Justin Jones提供的链接找到的那个好。他们有很多关于IP地址的解决方案,但这是排名第一的,使用LinqPad(我喜欢LinqPad),我进行的大多数测试都非常好。我建议使用这个而不是之前提供的任何表达式:

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

在LinqPad中尝试以下内容:

// \b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b  355.168.0.1 = 355.168.0.1 (Not Correct)
// ((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]?) 355.168.0.1 = 55.168.0.1 (Not correct)
// \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}  355.168.0.1 = 355.168.0.1 (Not Correct)
// ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$  355.168.0.1 = 355.168.0.1 (Not Correct)
// ^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$  355.168.0.1 = 355.168.0.1 (Not Correct)
// ^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$  355.168.0.1 = No Match (Correct)

Match match = Regex.Match("355.168.0.1", @"^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$");
if (match.Success) {
    Console.WriteLine(match.Value);
}
else {
    Console.WriteLine("No match.");
}

使用新的正则表达式,以下内容是无效的,这是正确的:355.168.0.1 = 不匹配,如评论中所述。
我欢迎任何对此进行微调的建议,因为我正在开发一个利用该表达式的工具,并且一直在寻找更好的方法来完成这项工作。
更新:我创建了一个.NET Fiddle项目,提供了一个使用各种值测试各种IP地址的列表,以及该表达式的工作示例。随意调整它并尝试各种值来执行此表达式,并在找到表达式失败的情况下提供任何输入。https://dotnetfiddle.net/JoBXdI 更新2:最好参考这篇文章:另一个相关问题。 谢谢,希望这能帮到你!

这个针对“0.254.255.0”返回false。 - dont_trust_me
@dont_trust_me 感谢您指出这一点。在我上面链接的 .NET Fiddle 项目中似乎可以正常工作(我已将您的示例添加到 fiddle 项目中)。"0.254.255.0 不匹配。(被认为是无效的)" - 您是如何得到有效的呢? - Erick Brown

3
Regex.IsMatch(input, @"^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$")

10
为什么你会在一个问题已经被回答一年之后,用一个无法解决问题的方案来回答它呢?这个问题是关于提取子字符串的,而你的解决方案只匹配一个完全相同的字符串,并且对之前的答案毫无帮助。 - Simon MᶜKenzie

3
避免使用/b - 它允许IP地址前后存在其他字符。
例如,...198.192.168.12...是有效的。
如果可以将输入拆分成可隔离IP地址的块,则改用^$
     Regex regexIP = new Regex(@"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$");

     if (regexIP.Match(textBoxIP.Text).Success){
         String myIP = textBoxIP.Text;
     }

注意:上面的代码不会验证数字,如172.316.254.1是正确的。这只检查格式是否正确。


更新:为了验证格式和数值,可以使用以下代码:

     Regex regexIP = new Regex(@"^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$");

     if (regexIP.Match(textBoxIP.Text).Success){
         String myIP = textBoxIP.Text;
     }

(注意对每个数字值使用([01]?[0-9]?[0-9] | 2 [0-4] [0-9] | 25 [0-5])
来源:https://stackoverflow.com/a/10682785/4480932

1

我从DataAnnotations命名空间的UrlAttribute.cs中采用了这个模式。正如您所看到的,我只从源代码中取了一小部分原始模式。

Regex.IsMatch(input, @"^(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-
9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-
9]\d|1\d\d|2[0-4]\d|25[0-5])$");

请解释一下,以便为那些实际上会搜索这个问题的人提供价值。对于那些可以理解您的代码而无需解释的人来说,解决方案已经很明显了。 - jpaugh
这个在我的 .NET Fiddle 项目中测试正确。不确定这个和我的表达式之间有什么大的区别。 - Erick Brown

0

使用正则表达式@"\A\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}\z" 进行尝试


这个不起作用,可以看看我上面的 .NET fiddle 链接,我已经把这个表达式添加到测试列表中了。 - Erick Brown

0

我认为你需要摆脱这个字符“-”,它是一个杂乱的字符还是什么?

Regex(@"[\b\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}\b")


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接