使用 regexp 验证 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

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

433052 次浏览

IPv4地址(精确捕获) 匹配0.0.0.0到255.255.255.255,但是捕获无效地址,如1.1.000.1 使用此正则表达式可精确匹配 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 库

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

你已经得到了一个可行的答案,但是为了防止你好奇你的原始方法有什么问题,答案是你需要在你的选择周围加上圆括号,否则只有当数字小于200时才需要 (\.|$)

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

^\\s*[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]\\s*

    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();
}
}
^((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        # This is an invalid IP address!

拒绝 :

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

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

(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}

我在为 IPv4地址寻找类似的东西-一个正则表达式,也停止通常使用的私有 IP 地址被验证(192.168.x。Y,10.x.Y.z,172.16.x.Y)所以使用负面预期来实现这一点:

(?!(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个独立的行上进行格式化) Regular expression visualization

调试演示

它可能不会优化速度,但只有在寻找“真正的”互联网地址时才能很好地工作。

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

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)

如果其他任何人正在寻找验证’互联网 IP 地址不包括公共私人地址’

-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,只匹配整个 addr 空间(包括广播等)。

目前最佳(43个字符)

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

这个版本在不使用负向前瞻(在某些正则表达式中是不支持的)的情况下,又将内容缩短了6个字符。

最新、最短、可读性最低的版本(49个字符)

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

[0-9]块可以在两个地方被 \d所取代——这使得它的可读性降低了一些,但是肯定更短。

更新,更短,可读性第二低的版本(55个字符)

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

这个版本寻找250-5病例,然后它聪明的手术所有可能的病例为 200-249 100-199 10-99病例。请注意,|)部分不是错误,而是实际上 OR 为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 可能以 .结束的情况

另一种答案,使用一些较新的技术(71个字符)

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

在不支持前瞻的正则表达式实现中非常有用

最古老的答案(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

我觉得这个最短。

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

这是正则表达式为我工作:
"\<((([1-9]|1[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([1-9]|1[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4]))\>"

String zeroTo255 = "([0-9]|[0-9][0-9]|(0|1)[0-9][0-9]|2[0-4][0-9]|25[0-5])";


it can contain single digit i.e ([0-9]);
It can contain two digits i.e ([0-9][0-9]);
range is (099 to 199)i.e((0|1)[0-9][0-9]);
range is (200 - 249) i.e (2[0-9][0-9]) ;
range is (250-255) i.e(25[0-5]);

我发现这个示例非常有用,而且它允许不同的 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
((\.|^)(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

查找一个有效的 IP 地址,只要该 IP 绕过除数字以外的任何字符(在 IP 之后或之前)。创建4个后向引用: $+ { first }。$+ { second }.$+ {第三}。$+ { 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.

用一个实际值替换每个八进制的一部分,但是你可以构建自己的 find 并替换它,这对修改文本文件中的 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

这比一些要长一些,但是这是我用来匹配 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])$

IPv4地址是一个非常复杂的东西。

注意 : 缩进和衬里仅用于说明目的,并不存在于真正的正则表达式中。

\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地址由上述正则表达式验证。

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

子网掩码:

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

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


你可以像上面那样想象各种各样的地址

(((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})匹配以 1开头的任何三位数字(1后跟任何两位数字) ,或者从 100199的数字。(2[0-4]\d)与数字 (\d{1,2})0到 (\d{1,2})1相匹配。(\d{1,2})2匹配数字 (\d{1,2})3到 (\d{1,2})4。这些子表达式中的每一个都包含在另一个子表达式中,每个子表达式之间有一个 (\d{1,2})5(这样四个子表达式中的一个必须匹配,而不是全部匹配)。在数字范围之后是 (\d{1,2})6以匹配 (\d{1,2})7,然后整个序列(所有的数字选项加上 (\d{1,2})6)被封装到另一个子表达式中,并使用 (\d{1,2})9重复三次。最后,重复数字的范围(这一次没有尾随 (\d{1,2})6)以匹配最终的 IP 地址号。通过将四个数字中的每一个限制为 0(\d{1,2})4之间的值,该模式确实可以匹配有效的 IP 地址并拒绝无效的地址。

节选自: Ben Forta“学习正则表达式”


如果在 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

我会使用 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个捕获组的唯一其他方法是重复这个模式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]

我能想象到的最精确、最直观和最紧凑的 IPv4 regexp 是

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

但是性能/效率怎么办... 对不起,我不知道,谁在乎呢?

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

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

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

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

扩展正则表达式:

/^[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上测试) :

虽然 Ruby 应该是 PCRE,但由于某种原因,Perl 5.18不允许使用这个 regex:

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

我所有这些测试都是在线 给你

试试这个:

\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
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

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

下面是验证 IP-Address 的正则表达式。

^((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]|[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})

演示

这个代码对我很有用,就这么简单。

这里我取了 ip 的值,并尝试将其与 regex 匹配。

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”,以此类推。 '''

这个匹配只匹配有效的 IP (没有预先设置的0,但它将匹配从0到255的八进制字节,不管它们的“功能”[即保留,私有等]) ,并允许内联匹配,其中可能有空格之前和/或之后的 IP,或当使用 CIDR 符号。

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


$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< '10.0.1.2'
10.0.1.2


$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< 'ip address 10.0.1.2'
ip address 10.0.1.2


$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< 'ip address 10.0.1.2 255.255.255.255'
ip address 10.0.1.2 255.255.255.255


$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< 'ip address 10.0.1.2/32'
ip address 10.0.1.2/32


$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< 'ip address 10.0.1.2.32'
$


$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< 'ip address10.0.1.2'
$


$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< '10.0.1.256'
$


$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< '0.0.0.0'
0.0.0.0


$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< '255.255.255.255'
255.255.255.255


$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< '255.255.255.256'
$

当然,在 IP 是内联的情况下,如果您只想要整个 IP 而只想要 IP,那么可以使用 grep 选项“-o”和您偏好的空格修剪器。

对于我们这些使用 python 的人来说,大致相当于:

>>> ipv4_regex = re.compile(r'(^| )((?:[1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(?:[1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])($| |/)')
>>> ipv4_regex.search('ip address 10.1.2.3/32')
<re.Match object; span=(10, 20), match=' 10.1.2.3/'>

如果你像我一样挑剔(懒惰) ,你可能更喜欢使用分组来获得整个 IP,只有 IP,或 CIDR,只有 CIDR 或它们的某种组合。我们可以使用 (? P)语法来命名我们的组,以便于参考。

>>> ipv4_regex = re.compile(r'(?:^| )(?P<address>((?:[1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(?:[1-9]?\d|1\d{2}|2[0-4]\d|25[0-5]))(?P<slash>/)?(?(slash)(?P<cidr>[0-9]|[12][0-9]|3[0-2]))(?:$| )')
>>> match = ipv4_regex.search('ip address 10.0.1.2/32')
>>> match.group('address')
'10.0.1.2'
>>> match.group('cidr')
'32'
>>> "".join((match.group('address'), match.group('slash'), match.group('cidr')))
'10.0.1.2/32'

当然,也有不只使用正则表达式的方法。这里有一些您可以检查的条件(这个条件没有查找内联,只是验证传递的地址是否有效)。

首先检查地址中的每个字符是一个数字还是一个’

下一步检查有正好3’

接下来的两个检查检查每个八位元组是否介于0和255之间。

最后一个检查是没有八进制字节预先使用’0’

def validate_ipv4_address(address):
return all(re.match('\.|\d', c) for c in address) \
and address.count('.') == 3 \
and all(0 <= int(octet) <= 255 for octet in address.split('.')) \
and all((len(bin(int(octet))) <= 10 for octet in address.split('.'))) \
and all(len(octet) == 1 or d[0] != '0' for octet in address.split('.'))




>>> validate_ipv4_address('255.255.255.255')
True
>>> validate_ipv4_address('10.0.0.1')
True
>>> validate_ipv4_address('01.01.01.01')
False
>>> validate_ipv4_address('123.456.789.0')
False
>>> validate_ipv4_address('0.0.0.0')
True
>>> validate_ipv4_address('-1.0.0.0')
False
>>> validate_ipv4_address('1.1.1.')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in validate_ipv4_address
File "<stdin>", line 4, in <genexpr>
ValueError: invalid literal for int() with base 10: ''
>>> validate_ipv4_address('.1.1.1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in validate_ipv4_address
File "<stdin>", line 4, in <genexpr>
ValueError: invalid literal for int() with base 10: ''
>>> validate_ipv4_address('1..1.1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in validate_ipv4_address
File "<stdin>", line 4, in <genexpr>
ValueError: invalid literal for int() with base 10: ''

(按位计算,每个八位元组应该是8位或更少,但每个八位元组前面加上’0b’)

>>> bin(0)
'0b0'
>>> len(bin(0))
3
>>> bin(255)
'0b11111111'
>>> len(bin(256))
11
/^(?:(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}(?1)$/m

演示

我在这个页面上看到了非常糟糕的正则表达式. . 所以我带来了我自己的:

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

说明:

num-group = (0-9|10-99|100-199|200-249|250-255)
<border> + { <num-group> + <dot-cahracter> }x3 + <num-group> + <border>

在这里您可以验证它是如何工作的 给你

对于从0到255的数字,我使用这个 regex:

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

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

因此,对于 IPv4,我使用这个 regex:

^(([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 (可变长度子网掩码) ,我使用这个 regex:

^(([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 列表,我使用这个 regex:

^("(([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”

也许它可能会变得更短,但对我来说,这是很容易理解这么好由我。

希望能有帮助!

我试着让它更简单,更短。

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

如果有人想知道它是如何工作的,这就是解释。真的很简单。试一试吧:

 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

我试着让它更简单,更短。

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

如果有人想知道它是如何工作的,这就是解释。真的很简单。试一试吧:

 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

用于 Java 的 IPV4地址的有效正则表达式

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

我的[扩展]方法→ regexp 用于空间分隔的 IP 地址:

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

使用 PCRE 预测。

试试这个

^ (127 | 10) . [0-9]{1,3} . [0-9]{1,3} . [0-9]{1,3}”

此模式不包括52个符号,并接受从零开始的块。

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

这里有一个更好的方法,它附带了通过/失败的 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])$/

接受

127.0.0.1
192.168.1.1
192.168.1.255
255.255.255.255
10.1.1.1
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
192.168.1.099

我的解决办法是:

^([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.0.0.0
255.255.255.255
123.123.123.123
127.0.0.1
192.168.0.1

但它不会匹配:

192.168.1.01
256.256.256.256
01.01.01.01

要验证有效范围为0.0.0.0至255.255.255.255的任何 IP 地址,可以使用以下非常简单的形式编写。

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

在文本中找到一个有效的 ip 地址是一个非常困难的问题


我有一个 regexp,它可以从文本文件中的字符串中匹配(提取)有效的 ip 地址。

我的 Regexp

\b(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\.)(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){2}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\b
  • 字界
  • 意味着启动非捕获组
  • 字符串 ^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\.)必须从右边第一个八位元开始,点字符
    • (? : 25[0-5] | 2[0-4][0-9] | 1[0-9][0-9] | [1-9][0-9] | [1-9])-找到第一个右八位元组-(第一个八位元组不能以 -0开始)
  • (?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){2}-查找下一个右两个带点字符串的八位数
  • 字符串 (?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\b必须以右第四个八位元结束(现在允许零字符)

但是这个 ip regexp 有少数假阳性匹配:

Https://regexr.com/69dk7

regexp for mostly right match for ip addresses

仅使用 regexp 无法从文本文件中查找或提取有效的 ip 地址。不检查其他条件,您总是得到假正匹配。

解决方案


我编写 一个班轮 perl来从文本文件中提取 ip 地址,它有以下条件:

  • 当 ip 地址位于行首时,下一个字符是一个或多个空白字符(空格、制表符、新行... ...)
  • 当 ip 地址在行尾时,新行是下一个字符,而 ip 地址之前是一个或多个空格字符
  • 在文本中间—— ip 地址之前和之后是一个或多个空格字符

结果是 perl 不匹配像 https://84.25.74.125和另一个 URI 字符串这样的字符串。或者 IP 地址在行尾,点字符在行尾。但是它会在文本中找到任何有效的 IP 地址。

Perl 一班轮解决方案:

$ cat ip.txt | perl -lane 'use warnings; use strict; for my $i (@F){if ($i =~/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\.)(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){2}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/) { print $i; } }'
36.42.84.233
158.22.45.0
36.84.84.233
12.0.5.4
1.25.45.36
255.3.6.5
4.255.2.1
127.0.0.1
127.0.0.5
126.0.0.1

测试文本文件:

$ cat ip.txt
36.42.84.233 stop 158.22.45.0 and 56.32.58.2.
25.36.84.84abc and abc2.4.8.2 is error.
1.2.3.4_
But false positive is 2.2.2.2.2.2.2.2 or 1.1.1.1.1
http://23.54.212.1:80
https://89.35.248.1/abc
36.84.84.233 was 25.36.58.4/abc/xyz&158.133.26.4&another_var
and 42.27.0.1:8333 in http://212.158.45.2:26
0.25.14.15 ip can not start with zero
2.3.0
abc 12.0.5.4
1.25.45.36
12.05.2.5
256.1.2.5
255.3.6.5
4.255.2.1
4.256.5.6
127.0.0.1 is localhost.
this ip 127.0.0.5 is not localhost
126.0.0.1

附录


对于来自其他星球的人,字符串 2130706433127.124.005.04.52是一个有效的 ip 地址,我有一个消息: 自己想办法解决吧! ! !

考虑到一些变体的建议,\d\b可能不被支持。因此,以防万一:

IPv4地址

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

测试: https://debuggex.com/r/izHiog3KkYztRMSJ

graph