使用正则表达式验证IPv4地址


90

我一直在尝试获得用于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

我进行了搜索以查看是否已被问到并回答过,但是其他答案似乎只是显示如何确定4组1-3个数字,或者对我不起作用。


12
别忘了A,AB和ABC是IP地址以及ABCD的有效形式。尝试ping 2130706433ping 127.1咯咯地笑。
dty

1
我的变体在线regexr.com/39hqf
Sllouyssgort 2014年

Answers:


97

您已经有了一个可行的答案,但是以防万一您想知道原始方法有什么问题,答案是您需要在轮替中加上括号,否则(\.|$)仅在数字小于200时才需要。

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

25
这似乎也验证了类似的东西192.168.1.1.1
cwd

2
它应该是:\b((?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:(?<!\.)\b|\.)){4}; 即,所以它以单词边界而不是行尾结尾?另外,在这里我标记了非捕获组,以避免不必要的子匹配。注意:这仍然没有考虑@dty的评论,因为我对这种形式的IP不熟悉。尽管他是对的,但它似乎是正确的。
JohnLBevan '16

您可能想尝试一下:(((1?\ d \ d?| 2 [0-4] \ d | 25 [0-5])\。){3}(1?\ d \ d?| 2 [0-4] \ d | 25 [0-5])
Morg。

这对于非捕获效果很好\b(?:(?:[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])\b
Appy

3
09.09.09.09认为是有效的IP?它也与此正则表达式匹配。但是ping会抛出类似的错误消息ping: cannot resolve 09.09.09.09: Unknown host。我认为将匹配减少为仅点十进制表示法匹配可能是明智的。该条目讨论了在IP地址领先的错误。
马瑞丰

79
^((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

拒绝

30.168.1.255.1
127.1
192.168.1.256
-1.2.3.4
1.1.1.1.
3...3

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


那“ 3 ... 3”的IP地址呢?使用此正则表达式可以接受3 ... 3
Ankur Loriya 2014年

7
那1.1.1.01呢?它被视为有效的IPv4地址吗?谢谢。
odieatla

此正则表达式1.1.1.01视为有效的IPv4地址。在线单元测试debuggex.com/r/-EDZOqxTxhiTncN6/1
Sllouyssgort

顺便说一句,^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}$得到相同的结果debuggex.com/r/mz_-0dEm3wseIKqK,与@Mark Byers答案非常相似
Sllouyssgort

@PriteshAcharya在这里工作正常。
Kid Diamond

34

最新,最短,可读性最低的版本(55个字符

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

此版本寻找250-5案例,然后对200-249 100-199 10-99案例的所有可能案例进行巧妙的逻辑运算。请注意,该|)部分不是错误,但实际上是对0-9范围的最后一种情况进行或运算。我也省略了?:非捕获组部分,因为我们并不真正关心捕获的项目,如果我们一开始没有完全匹配,则不会以任何方式捕获它们。

旧版本和较短版本(可读性较低)(63个字符

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

较旧(可读)版本(70个字符

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

它使用否定前移(?!)来消除ip可能以a结尾的情况.

最早的答案(115个字符

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

我认为这是最准确,最严格的正则表达式,它无法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])
anneb

1
@tinmarino我还原了您的编辑,因为它允许诸如192.168.000.1之类的无效地址。希望编辑此答案的任何人,请先在此处进行评论,以避免出现此类问题-我通常会很快答复。当然,总是在寻找更短/更好的解决方案。
Danail Gabenski

1
@DanailGabenski(和其他)用于存储,您解决了将其替换为last的问题[01]?[0-9][0-9]?1[0-9]{2}|[1-9]?[0-9]因为您不喜欢前导0。再次感谢!我会将您的解决方案放在我的regex主箱中。
Tinmarino '19

1
@tinmarino是的,尽管尚未被官方接受点号十进制格式已成为ipv4的标准,请查看以下内容。特别是第3点,其中提出了草案但已过期。验证如此严格的第二个原因是,当在用户界面中显示时,ip的非小数位数(例如023而不是23)会使用户觉得这是一个错误/错误。由于023需要转换为23以避免重复等,因此也会导致验证/安全性方面的困难。感谢您尝试使事情变得更好!
Danail Gabenski

1
你可以把它缩短了通过分解出[0-9]2[0-4]1和更短的情况下。 ^(?:(25[0-5]|(?:2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}$
克莱顿·辛格

12

IPv4地址(准确捕获),匹配0.0.0.0到255.255.255.255。使用此正则表达式可以准确匹配IP地址。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

取自JGsoft RegexBuddy库

编辑:这(\.|$)部分似乎很奇怪


2
真好!我对似乎有效的方法做了更有效的修改:"\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$){4}\b-谢谢!
Matthieu卡地亚

2
@MatthieuCartier您有效的正则表达式模式对我不起作用
R__raki__

255.255.255.000是不是一个有效的IP
斯特凡Grillon的

6

我在寻找类似的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}

(这些当然应该在一行上,为了便于阅读,请在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

将(并且应该)起作用的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)

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


5

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

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

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

/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/

扩展正则表达式(ERE):

/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/

要么:

/^([0-9]+(\.|$)){4}/

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

/^\d+\.\d+\.\d+\.\d+$/

要么:

/^(\d+(\.|$)){4}/

Ruby(在Ruby 2.1上测试):

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

/^(\d+[\.$]){4}/

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


3

这比一些要长一些,但这就是我用来匹配IPv4地址的方式。简单而毫不妥协。

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

3

上面的答案是有效的,但是如果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

输出文字:

0.0.0.0
255.255.255.255
192.168.0.1
254.254.254.254
172.24.1.210
200.200.200.200

1
在我投票之前,这是负面的。我一直在尝试完全做到这一点(比我想承认的还要多的时间)。它不会捕获在一行上具有多个点四进制的行,但是对于我的用例,我可以接受。这是一个很好的答案,需要更多票!
天文学

3

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

在这里,我采用了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")

以上条件检查所有4个八位位组的值是否都超过255,那么它是无效的。但在应用条件之前,由于值在字符串中,因此必须将它们转换为整数。

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


欢迎使用StackOverflow。如果您可以花一些时间解释为什么您的答案应该可以解决OP问题,那将是很棒的。仅代码答案通常是错误的答案,因为它们无法帮助其他编码人员理解他们做错了什么。
Davide Vitali

在代码中使用适当的缩进以使其对用户可读
Syed Mehtab Hassan

2

我设法从所有其他答案构造一个正则表达式。

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

根据IEEE 802.x以太网标准,IP验证不得为IP范围0.xxx >>>-无效的IP。#1.IP范围从1.xxx到126.xxx >>>>可以进行配置。#2.IP范围127.xxx >>>>不允许-无效的IP。#3.IP范围128.xxx至223.xxx >>可以配置。建议使用更好的处理方式,如下所示:^(22 [0-3] | 2 [0-1] [0-9] | [1] [0-9] [0-9]?| [1-9 ] [0-9] | [1-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-4] | 2 [0-4] [0-9] | [01]?[0-9] [0-9]?)$
Yogesh Aggarwal


2

对于0到255之间的数字,我使用此正则表达式:

(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))

上面的正则表达式将匹配从0到255的整数,但不匹配256。

因此,对于IPv4,我使用以下正则表达式:

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

它是这种结构:^(N)((\.(N)){3})$其中N是用于匹配0到255之间的数字的正则表达式。
此正则表达式将匹配IP,如下所示:

0.0.0.0
192.168.1.2

但以下内容除外:

10.1.0.256
1.2.3.
127.0.1-2.3

对于IPv4 CIDR(无类域间路由),我使用此正则表达式:

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

它是这种结构:^(N)((\.(N)){3})\/M$其中N是用于匹配0到255之间的数字的正则表达式,而M是用于匹配0到32之间的数字的正则表达式。
该正则表达式将匹配CIDR,如下所示:

0.0.0.0/0
192.168.1.2/32

但以下内容除外:

10.1.0.256/16
1.2.3./24
127.0.0.1/33

对于像"10.0.0.0/16", "192.168.1.1/32"我这样的正则表达式的IPv4 CIDR列表:

^("(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})\/(([0-9])|([12][0-9])|(3[0-2]))")((,([ ]*)("(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})\/(([0-9])|([12][0-9])|(3[0-2]))"))*)$

它的结构如下:^(“C”)((,([ ]*)(“C”))*)$其中C是用于匹配CIDR的正则表达式(如0.0.0.0/0)。
此正则表达式将匹配CIDR列表,如下所示:

“10.0.0.0/16”,”192.168.1.2/32”, “1.2.3.4/32”

但以下内容除外:

“10.0.0.0/16” 192.168.1.2/32 “1.2.3.4/32”

也许它会变得更短,但是对我来说,我很容易理解它。

希望能帮助到你!


欢迎来到SO,我们感谢您的投入!您能否详细说明一下不同的正则表达式在做什么(尤其是最后一个)?
B–rian

1

带子网掩码:

^$|([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\
.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\
.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\
.([01]?\\d\\d?|2[0-4]\\d|25[0-5])
((/([01]?\\d\\d?|2[0-4]\\d|25[0-5]))?)$

1
(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))\.){3}(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2})))

测试以查找文本中的匹配项, https://regex101.com/r/9CcMEN/2

以下是定义IP地址每个数字中有效组合的规则:

  • 任何一位或两位数字。
  • 以开头的任何三位数1

  • 2如果第二个数字是0 通过,则以开头的任何三位数4

  • 任何三位数年初25如果第三位是0 通过5

让我们从开始(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))\.),一组四个嵌套的子表达式,我们将以相反的顺序看它们。(\d{1,2})匹配的任何一个或两个数字的数字或数字099(1\d{2})任何三位数起始与匹配11后面为两个任意数字),或数字100通过199。通过(2[0-4]\d)匹配数字。通过匹配数字。这些子表达式中的每一个都包含在另一个子表达式中,并且每个子表达式之间有一个子表达式(因此,四个子表达式之一必须匹配,而不是全部匹配)。在数字范围匹配之后,然后是整个系列(所有数字选项加上200249(25[0-5])250255|\..\.)包含在另一个子表达式中,并使用重复三遍{3}。最终,重复数字范围(这次没有结尾\.),以匹配最终的IP地址数字。通过将四个数字中的每个数字限制为0和之间的值255,此模式确实可以匹配有效IP地址并拒绝无效地址。

摘自:本·福塔。“学习正则表达式。”


如果没有一个角色是在IP地址的开始也没有结束时想,^$元字符应该分别使用。

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

测试以查找文本中的匹配项, https://regex101.com/r/uAP31A/1


1

我试图使其更简单,更短。

^(([01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}([01]?\d{1,2}|2[0-4]\d|25[0-5])$

如果您正在寻找java / kotlin:

^(([01]?\\d{1,2}|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d{1,2}|2[0-4]\\d|25[0-5])$

如果有人想知道它是如何工作的,那就是解释。真的很简单。只需尝试一下:p:

 1. ^.....$: '^' is the starting and '$' is the ending.

 2. (): These are called a group. You can think of like "if" condition groups.

 3. |: 'Or' condition - as same as most of the programming languages.

 4. [01]?\d{1,2}: '[01]' indicates one of the number between 0 and 1. '?' means '[01]' is optional. '\d' is for any digit between 0-9 and '{1,2}' indicates the length can be between 1 and 2. So here the number can be 0-199.

 5. 2[0-4]\d: '2' is just plain 2. '[0-4]' means a number between 0 to 4. '\d' is for any digit between 0-9. So here the number can be 200-249.

 6. 25[0-5]: '25' is just plain 25. '[0-5]' means a number between 0 to 5. So here the number can be 250-255.

 7. \.: It's just plan '.'(dot) for separating the numbers.

 8. {3}: It means the exact 3 repetition of the previous group inside '()'.

 9. ([01]?\d{1,2}|2[0-4]\d|25[0-5]): Totally same as point 2-6

数学上是这样的:

(0-199 OR 200-249 OR 250-255).{Repeat exactly 3 times}(0-199 OR 200-249 OR 250-255)

因此,如您通常所见,这就是IP地址的模式。希望对理解正则表达式有所帮助。:p


1

我试图使其更简单,更短。

^(([[01]?\ d {1,2} | 2 [0-4] \ d | 25 [0-5])。){3}([01]?\ d {1,2} | 2 [0-4] \ d | 25 [0-5])$

如果您正在寻找java / kotlin:

^(([[01]?\ d {1,2} | 2 [0-4] \ d | 25 [0-5])\。){3}([01]?\ d {1,2} | 2 [0-4] \ d | 25 [0-5])$

如果有人想知道它是如何工作的,那就是解释。真的很简单。只需尝试一下:p:

 1. ^.....$: '^' is the starting and '$' is the ending.

 2. (): These are called a group. You can think of like "if" condition groups.

 3. |: 'Or' condition - as same as most of the programming languages.

 4. [01]?\d{1,2}: '[01]' indicates one of the number between 0 and 1. '?' means '[01]' is optional. '\d' is for any digit between 0-9 and '{1,2}' indicates the length can be between 1 and 2. So here the number can be 0-199.

 5. 2[0-4]\d: '2' is just plain 2. '[0-4]' means a number between 0 to 4. '\d' is for any digit between 0-9. So here the number can be 200-249.

 6. 25[0-5]: '25' is just plain 25. '[0-5]' means a number between 0 to 5. So here the number can be 250-255.

 7. \.: It's just plan '.'(dot) for separating the numbers.

 8. {3}: It means the exact 3 repetition of the previous group inside '()'.

 9. ([01]?\d{1,2}|2[0-4]\d|25[0-5]): Totally same as point 2-6

数学上是这样的:

(0-199 OR 200-249 OR 250-255).{Repeat exactly 3 times}(0-199 OR 200-249 OR 250-255)

因此,如您通常所见,这就是IP地址的模式。希望对理解正则表达式有所帮助。:p


0
    const char*ipv4_regexp = "\\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";

我将JGsoft RegexBuddy库中的正则表达式改编为C语言(regcomp / regexec),发现它可以工作,但是在某些操作系统(如Linux)中存在一些问题。该正则表达式接受ipv4地址,例如192.168.100.009,其中Linux中的009被视为八进制值,因此该地址不是您认为的地址。我将正则表达式更改如下:

    const char* ipv4_regex = "\\b(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
           "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
           "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
           "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\b";

现在使用该正则表达式192.168.100.009不是有效的ipv4地址,而192.168.100.9可以。

我也修改了多播地址的正则表达式,如下所示:

    const char* mcast_ipv4_regex = "\\b(22[4-9]|23[0-9])\\."
                        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
                        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]?)\\."
                        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\b";

我认为您必须使正则表达式适应用于开发应用程序的语言

我在Java中举了一个例子:

    package utility;

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;

    public class NetworkUtility {

        private static String ipv4RegExp = "\\b(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d?)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d?)\\b";

        private static String ipv4MulticastRegExp = "2(?:2[4-9]|3\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d?|0)){3}";

        public NetworkUtility() {

        }

        public static boolean isIpv4Address(String address) {
            Pattern pattern = Pattern.compile(ipv4RegExp);
            Matcher matcher = pattern.matcher(address);

            return matcher.matches();
        }

        public static boolean isIpv4MulticastAddress(String address) {
             Pattern pattern = Pattern.compile(ipv4MulticastRegExp);
             Matcher matcher = pattern.matcher(address);

             return matcher.matches();
        }
    }

0
-bash-3.2$ echo "191.191.191.39" | egrep 
  '(^|[^0-9])((2([6-9]|5[0-5]?|[0-4][0-9]?)?|1([0-9][0-9]?)?|[3-9][0-9]?|0)\.{3}
     (2([6-9]|5[0-5]?|[0-4][0-9]?)?|1([0-9][0-9]?)?|[3-9][0-9]?|0)($|[^0-9])'

>> 191.191.191.39

(这是一个与整个地址空间(包括广播等)匹配的DFA)。



0

我发现此示例非常有用,此外它还允许使用不同的ipv4表示法。

使用python的示例代码:

    def is_valid_ipv4(ip4):
    """Validates IPv4 addresses.
    """
    import re
    pattern = re.compile(r"""
        ^
        (?:
          # Dotted variants:
          (?:
            # Decimal 1-255 (no leading 0's)
            [3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
          |
            0x0*[0-9a-f]{1,2}  # Hexadecimal 0x0 - 0xFF (possible leading 0's)
          |
            0+[1-3]?[0-7]{0,2} # Octal 0 - 0377 (possible leading 0's)
          )
          (?:                  # Repeat 0-3 times, separated by a dot
            \.
            (?:
              [3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
            |
              0x0*[0-9a-f]{1,2}
            |
              0+[1-3]?[0-7]{0,2}
            )
          ){0,3}
        |
          0x0*[0-9a-f]{1,8}    # Hexadecimal notation, 0x0 - 0xffffffff
        |
          0+[0-3]?[0-7]{0,10}  # Octal notation, 0 - 037777777777
        |
          # Decimal notation, 1-4294967295:
          429496729[0-5]|42949672[0-8]\d|4294967[01]\d\d|429496[0-6]\d{3}|
          42949[0-5]\d{4}|4294[0-8]\d{5}|429[0-3]\d{6}|42[0-8]\d{7}|
          4[01]\d{8}|[1-3]\d{0,9}|[4-9]\d{0,8}
        )
        $
    """, re.VERBOSE | re.IGNORECASE)
    return pattern.match(ip4) <> None

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

此正则表达式将不接受08.8.8.8或8.08.8.8或8.8.08.8或8.8.8.08


例如,这个错过了127.0.0.1和0.0.0.0
anneb '17

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

1
根据规范,拒绝前导零是正确的。
John Haugeland

0

只要将IP包裹在除数字之外的其他任何字符(位于IP的后面或前面)中,就查找有效的IP地址。已创建4个反向引用:$ + {first}。$ + {second}。$ + {third}。$ + {forth}

Find String:
#any valid IP address
(?<IP>(?<![\d])(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))
#only valid private IP address RFC1918
(?<IP>(?<![\d])(:?(:?(?<first>10)[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5])))|(:?(?<first>172)[\.](?<second>(:?1[6-9])|(:?2[0-9])|(:?3[0-1])))|(:?(?<first>192)[\.](?<second>168)))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))

Notepad++ Replace String Option 1: Replaces the whole IP (NO Change):
$+{IP}

Notepad++ Replace String Option 2: Replaces the whole IP octect by octect (NO Change)
$+{first}.$+{second}.$+{third}.$+{forth}

Notepad++ Replace String Option 3: Replaces the whole IP octect by octect (replace 3rd octect value with 0)
$+{first}.$+{second}.0.$+{forth}
NOTE: The above will match any valid IP including 255.255.255.255 for example and change it to 255.255.0.255 which is wrong and not very useful of course.

用实际值替换每个八进制的一部分,但是您可以构建自己的查找并替换,这对于修改文本文件中的IP非常有用:

for example replace the first octect group of the original Find regex above:
(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))
with
(?<first>10)

and
(?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))
with
(?<second>216)
and you are now matching addresses starting with first octect 192 only

Find on notepad++:
(?<IP>(?<![\d])(?<first>10)[\.](?<second>216)[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))

您仍然可以使用反向引用组以与以前完全相同的方式执行“替换”。

您可以大致了解以下内容:

cat ipv4_validation_test.txt
Full Match:
0.0.0.1
12.108.1.34
192.168.1.1
10.249.24.212
10.216.1.212
192.168.1.255
255.255.255.255
0.0.0.0


Partial Match (IP Extraction from line)
30.168.1.0.1
-1.2.3.4
sfds10.216.24.23kgfd
da11.15.112.255adfdsfds
sfds10.216.24.23kgfd


NO Match
1.1.1.01
3...3
127.1.
192.168.1..
192.168.1.256
da11.15.112.2554adfdsfds
da311.15.112.255adfdsfds

使用grep,您可以看到以下结果:

From grep:
grep -oP '(?<IP>(?<![\d])(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))' ipv4_validation_test.txt
0.0.0.1
12.108.1.34
192.168.1.1
10.249.24.212
10.216.1.212
192.168.1.255
255.255.255.255
0.0.0.0
30.168.1.0
1.2.3.4
10.216.24.23
11.15.112.255
10.216.24.23


grep -P '(?<IP>(?<![\d])(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))' ipv4_validation_test.txt
0.0.0.1
12.108.1.34
192.168.1.1
10.249.24.212
10.216.1.212
192.168.1.255
255.255.255.255
0.0.0.0
30.168.1.0.1
-1.2.3.4
sfds10.216.24.23kgfd
da11.15.112.255adfdsfds
sfds10.216.24.23kgfd


#matching ip addresses starting with 10.216
grep -oP '(?<IP>(?<![\d])(?<first>10)[\.](?<second>216)[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))' ipv4_validation_test.txt
10.216.1.212
10.216.24.23
10.216.24.23

0

IPv4地址是一件非常复杂的事情。

注意:缩进和衬砌仅用于说明目的,在实际的RegEx中不存在。

\b(
  ((
    (2(5[0-5]|[0-4][0-9])|1[0-9]{2}|[1-9]?[0-9])
  |
    0[Xx]0*[0-9A-Fa-f]{1,2}
  |
    0+[1-3]?[0-9]{1,2}
  )\.){1,3}
  (
    (2(5[0-5]|[0-4][0-9])|1[0-9]{2}|[1-9]?[0-9])
  |
    0[Xx]0*[0-9A-Fa-f]{1,2}
  |
    0+[1-3]?[0-9]{1,2}
  )
|
  (
    [1-3][0-9]{1,9}
  |
    [1-9][0-9]{,8}
  |
    (4([0-1][0-9]{8}
      |2([0-8][0-9]{7}
        |9([0-3][0-9]{6}
          |4([0-8][0-9]{5}
            |9([0-5][0-9]{4}
              |6([0-6][0-9]{3}
                |7([0-1][0-9]{2}
                  |2([0-8][0-9]{1}
                    |9([0-5]
    ))))))))))
  )
|
  0[Xx]0*[0-9A-Fa-f]{1,8}
|
  0+[1-3]?[0-7]{,10}
)\b

这些IPv4地址已通过上述RegEx验证。

127.0.0.1
2130706433
0x7F000001
017700000001
0x7F.0.0.01 # Mixed hex/dec/oct
000000000017700000001 # Have as many leading zeros as you want
0x0000000000007F000001 # Same as above
127.1
127.0.1

这些被拒绝。

256.0.0.1
192.168.1.099 # 099 is not a valid number
4294967296 # UINT32_MAX + 1
0x100000000
020000000000

0

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


上面是IP地址的正则表达式,例如:221.234.000.112也用于221.234.0.112、221.24.03.112、221.234.0.1


您可以想象以上各种地址


0

我将使用PCRE和define关键字:

/^
 ((?&byte))\.((?&byte))\.((?&byte))\.((?&byte))$
 (?(DEFINE)
     (?<byte>25[0-5]|2[0-4]\d|[01]?\d\d?))
/gmx

演示:https : //regex101.com/r/IB7j48/2

这样做的原因是避免重复(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)图案四次。其他解决方案(例如下面的解决方案)效果很好,但是它并不能像许多人所要求的那样捕获每个组。

/^((\d+?)(\.|$)){4}/ 

具有4个捕获组的唯一其他方法是将模式重复四次:

/^(?<one>\d+)\.(?<two>\d+)\.(?<three>\d+)\.(?<four>\d+)$/

因此,在perl中捕获ipv4非常容易

$ echo "Hey this is my IP address 138.131.254.8, bye!" | \
  perl -ne 'print "[$1, $2, $3, $4]" if \
    /\b((?&byte))\.((?&byte))\.((?&byte))\.((?&byte))
     (?(DEFINE)
        \b(?<byte>25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))
    /x'

[138, 131, 254, 8]

0

我能想到的最精确,最直接,最紧凑的IPv4正则表达式是

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

但是...的性能如何?对不起,我不知道,谁在乎?


0

试试这个:

\b(([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\.([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\.([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\.(2[0-5][0-5]|1[0-9][0-9]|[1-9][0-9]|[1-9]))\b

0
ip address can be from 0.0.0.0 to 255.255.255.255

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

(0|1)?[0-9][0-9]? - checking value from 0 to 199
2[0-4][0-9]- checking value from 200 to 249
25[0-5]- checking value from 250 to 255
[.] --> represent verify . character 
{3} --> will match exactly 3
$ --> end of string


0

简单的方法

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

演示版

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.