使用regexp验证IPv4地址

Mat*_*ier 61 regex validation grep ip-address ipv4

我一直试图获得有效的IPv4验证正则表达式,但没有太多运气.似乎我曾经有过它(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4},但它会产生一些奇怪的结果:

$ 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
Run Code Online (Sandbox Code Playgroud)

我做了一个搜索,看看是否已经被问及回答,但其他答案似乎只是显示如何确定4组1-3个数字,或者不适合我.

有任何想法吗?谢谢!

Mar*_*ers 77

你已经得到了一个有效的答案,但万一你好奇你的原始方法出了什么问题,答案是你需要围绕你的交替使用括号,否则(\.|$)只有在数字小于200时才需要.

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

  • 这似乎也验证了像`192.168.1.1.1`这样的东西 (17认同)
  • `09.09.09.09` 是否被视为有效 IP?它也被这个正则表达式匹配。但是 ping 会抛出类似“ping:无法解析 09.09.09.09:未知主机”的错误消息。我认为将匹配减少到仅点十进制符号匹配可能是明智的。此 [条目](https://superuser.com/questions/857603/are-ip-addresses-with-and-without-leading-zeroes-the-same) 讨论了 IP 地址中的主要错误。 (3认同)
  • 应该是:`\ b((?:25 [0-5] | 2 [0-4] [0-9] | [01]?[0-9] [0-9]?)(?:( ?&lt;!\。)\ b | \。)){4}`; 即,所以它以单词边界而不是行尾结尾?另外,在这里我标记了非捕获组,以避免不必要的子匹配。注意:这仍然没有考虑@dty的评论,因为我对这种形式的IP不熟悉。尽管他是对的,但它似乎是正确的。 (2认同)
  • 不要停在这里,@danail-gabenski 下面的答案提供了另一个处理更多边缘情况的正则表达式。 (2认同)

Sll*_*ort 60

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

接受:

127.0.0.1
192.168.1.1
192.168.1.255
255.255.255.255
0.0.0.0
1.1.1.01
Run Code Online (Sandbox Code Playgroud)

拒绝:

30.168.1.255.1
127.1
192.168.1.256
-1.2.3.4
3...3
Run Code Online (Sandbox Code Playgroud)

使用单元测试在线尝试:https://www.debuggex.com/r/-EDZOqxTxhiTncN6/1

  • 那1.1.1.01呢?它是否被视为有效的IPv4地址?谢谢。 (3认同)
  • 看看https://www.debuggex.com/您可以添加正则表达式的图形! (2认同)

Tim*_*Tim 30

正则表达式不是这项工作的工具.编写一个分隔四个数字的解析器并检查它们是否在[0,255]范围内会更好.非功能性正则表达式已经不可读了!

  • 所有的正则表达式都是不可读的;-)但仅凭这一点并不能使它成为错误的工具.事实上,我认为正则表达式是一个非常好的IP地址验证工具. (23认同)
  • @Spudley:有完全可读的正则表达式,例如`/\w + /`.正则表达式不适合的原因是这个问题与字符串的_meaning_有关.正则表达式旨在识别表单而不是比较数字. (10认同)
  • 这不是一个答案,它应该包括一个解析器,表明它比正则表达式更"简单".阅读答案,显然解析器应该"只"一两条简单的线条? (5认同)
  • Raymond Chen在此主题上有一篇很好的文章:http://blogs.msdn.com/b/oldnewthing/archive/2006/05/22/603788.aspx (2认同)

Dan*_*ski 17

新的和改进的短版本

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

它使用负向前瞻(?!)来移除ip可能以a结尾的情况.

老答案

^(?:(?: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])$ 
Run Code Online (Sandbox Code Playgroud)

我认为这是最准确和最严格的正则表达式,它不接受像000.021.01.0.这样的大多数其他答案似乎做的事情并且需要额外的正则表达式来拒绝类似于那个的情况 - 即0起始数字和以结尾的ip结尾.

  • 这是迄今为止该线程中唯一正确的答案。其他人错过了诸如“0.0.0.0”之类的地址或接受诸如“033.033.33.033”之类的八进制/十进制混合符号,甚至允许使用 999.999.999.999。这个比这个答案短 10 个字符的正则表达式怎么样:`(([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])` (3认同)
  • 您可以通过为“2[0-4]”、“1”和更短的情况分解“[0-9]”来使其更短。`^(?:(25[0-5]|(?:2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$ )|$)){4}$` (3认同)

Val*_*rij 9

IPv4地址(准确捕获)匹配0.0.0.0到255.255.255.255使用此正则表达式将IP编号与accurracy匹配.4个数字中的每一个都存储在捕获组中,因此您可以访问它们以进行进一步处理.

\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
Run Code Online (Sandbox Code Playgroud)

取自JGsoft RegexBuddy库

编辑:这(\.|$)部分看起来很奇怪

  • 太好了!我做了一个更有效的修改似乎工作:"\ b(25 [0-5] | 2 [0-4] [0-9] | [01]?[0-9] [0-9 ]?)(\.| $){4}\b` - 谢谢! (2认同)
  • @MatthieuCartier 你高效的正则表达式模式对我不起作用, (2认同)

Ale*_*vey 7

我认为许多阅读这篇文章的人会寻找更简单的正则表达式,即使它们匹配一些技术上无效的 IP 地址。(而且,正如其他地方所述,正则表达式可能不是正确验证 IP 地址的正确工具。)

如果您不想匹配行的开头/结尾,请删除^并在适用的情况下替换$\b

基本正则表达式 (BRE)(在 GNU grep、GNU sed 和 vim 上测试):

/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/
Run Code Online (Sandbox Code Playgroud)

扩展正则表达式 (ERE):

/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/
Run Code Online (Sandbox Code Playgroud)

或者:

/^([0-9]+(\.|$)){4}/
Run Code Online (Sandbox Code Playgroud)

Perl 兼容的正则表达式 (PCRE)(在 Perl 5.18 上测试):

/^\d+\.\d+\.\d+\.\d+$/
Run Code Online (Sandbox Code Playgroud)

或者:

/^(\d+(\.|$)){4}/
Run Code Online (Sandbox Code Playgroud)

Ruby(在 Ruby 2.1 上测试):

尽管应该是 PCRE,但无论出于何种原因,Ruby 都允许使用 Perl 5.18 不允许的正则表达式:

/^(\d+[\.$]){4}/
Run Code Online (Sandbox Code Playgroud)

我对所有这些的测试都在这里在线。


Shr*_*hal 6

'''这段代码对我有用,就这么简单。

在这里,我获取了 ip 的值,并尝试将其与正则表达式进行匹配。

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")
Run Code Online (Sandbox Code Playgroud)

上述条件检查所有 4 个八位字节的值是否超过 255,则该值无效。但在应用条件之前,我们必须将它们转换为整数,因为该值位于字符串中。

group(0) 打印匹配的输出,而 group(1) 打印第一个匹配的值,这里是“25”,依此类推。'''


abh*_*yan 6

这是一个更好的,附有通过/失败的 IP

/^((?:[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])$/
Run Code Online (Sandbox Code Playgroud)

接受

127.0.0.1
192.168.1.1
192.168.1.255
255.255.255.255
10.1.1.1
0.0.0.0
Run Code Online (Sandbox Code Playgroud)

拒绝

1.1.1.01
30.168.1.255.1
127.1
192.168.1.256
-1.2.3.4
1.1.1.1.
3...3
192.168.1.099
Run Code Online (Sandbox Code Playgroud)


Phi*_*mes 5

我正在寻找类似的IPv4地址-一个正则表达式,它也停止了对常用专用IP地址的验证(192.168.xy,10.xyz,172.16.xy),因此使用否定性的先见之明来完成此操作:

(?!(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}
Run Code Online (Sandbox Code Playgroud)

(这些当然应该在一行上,为了便于阅读,请在3条单独的行上进行格式化) 正则表达式可视化

Debuggex演示

它可能没有针对速度进行优化,但是在仅查找“真实”互联网地址时效果很好。

将会(也应该)失败的事情:

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
Run Code Online (Sandbox Code Playgroud)

将(并且应该)起作用的IP:

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)
Run Code Online (Sandbox Code Playgroud)

如果其他人正在寻找验证“ Internet IP地址(不包括公共专用地址)”的情况下提供


小智 5

上面的答案是有效的,但是如果 ip 地址不在行尾而是在文本之间怎么办?这个正则表达式甚至可以解决这个问题。

代码:'\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'

输入文本文件:

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
Run Code Online (Sandbox Code Playgroud)

输出文本:

0.0.0.0
255.255.255.255
192.168.0.1
254.254.254.254
172.24.1.210
200.200.200.200
Run Code Online (Sandbox Code Playgroud)


Eti*_*ier 5

/^(?:(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}(?1)$/m
Run Code Online (Sandbox Code Playgroud)

演示