我有一个正则表达式来匹配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]?)$
现在我想要相同的正则表达式,但是要使用逗号分隔的IPv4地址列表
示例(不能用逗号结尾字符串):
172.24.64.100.0,172.25.64.100.0,172.26.64.100
我该怎么做?
谢谢
答案 0 :(得分:0)
如果该语言支持PCRE(PHP)引擎,则可以使用以下正则表达式。请注意,它使用子例程。
(?=(25[0-5]|2[1-4]\d|1\d{2}|[1-9]\d|[1-9])){0}(?=((?1)(?:\.(?1)){3})){0}(?=(?2)(?:,(?2))*$)(?2)
正则表达式执行以下操作。
定义捕获组1
(?= # begin positive lookahead
( # begin capture group 1
25[0-5] # match 250-255
| # or
2[0-4]\d # match 200-249
| # or
1\d{2} # match 100-199
| # or
[1-9]\d # match 10-99
| # or
[1-9] # match 1-9
) # end capture group 1
) # end positive lookahead
{0} # execute postive lookahead zero times
定义捕获组2
(?= # begin positive lookahead
( # begin cap grp 2
(?1) # execute cap grp 1 instructions
(?: # begin non-cap grp
\.(?1) # match '.' then execute cap grp 1 instructions
{3} # end non-cap grp
) # end cap grp 2
) # end positive lookahead
{0} # execute postive lookahead zero times
确认字符串仅包含逗号分隔的有效IPv4地址
(?= # begin positive lookahead
(?2) # execute cap grp 2 instructions
(?: # begin non-cap grp
,(?2) # match ',' then execute cap grp 2 instructions
) # end non-cap grp
* # execute non-cap grp 0+ times
$ # match end of line
) # end positive lookahead
匹配IPv4地址
(?2) # execute cap grp 2 instructions
某些支持子例程(或 subexpressions )的正则表达式引擎可能具有不同的语法。例如,Ruby使用\g<1>
而不是(?1)
。可以选择使用命名的捕获组。 PCRE将(?P>sue)
用于名为“ sue”的捕获组。有关详细信息,请参见this discussion。
如果不希望使用子例程,或者该语言的正则表达式引擎不支持子例程(我理解,Python是其中之一),则可以用捕获组1的内容替换(?1)
,例如:< / p>
25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|[1-9]
自然,正则表达式的大小会大大增加(考虑替换(?2)
)。使用子例程的另一个优点是每个子例程可以单独进行测试。
非正则表达式方法
我认为开发上述正则表达式是一种练习(也是向某些读者介绍正则表达式子例程的机会),但是我不建议使用这种方法来支持普通语言工具的使用。例如,在Ruby中,仅需要几行代码,如下所示。那些不熟悉Ruby的人应该能够了解代码中正在发生的事情。
require 'ipaddr'
def ipv4s(str)
str.split(',').map do |s|
i = IPAddr.new(s)
raise ArgumentError, "'#{s}' is not an IP address" if i.nil?
raise ArgumentError, "'#{s}' is not an IPv4 address" unless i.ipv4?
s
end
end
ipv4s("172.24.64.100,172.25.64.100,172.26.64.100")
#=> "2001:0DB8:AC10:FE01:0000:0000:0000:0000"
ipv4s("172.24.64.100, 172.25.64.100,172.26.64.100")
#=> IPAddr::InvalidAddressError ( 172.25.64.100)
^
ipv4s("172.2403.64.100,172.25.64.100,172.26.64.100")
#=> IPAddr::InvalidAddressError (72.2403.64.100)
^^^^
ipv4s("cat 172.24.64.100,172.25.64.100,172.26.64.100")
#=> IPAddr::InvalidAddressError (cat 172.24.64.100)
^^^^
ipv4s("172.24.64.100,172.25.64.275,172.26.64.100")
#=> IPAddr::InvalidAddressError (172.25.64.275)
^^^