假设我有一个可能包含一个或多个IP地址的字符串。如何匹配所有这些,只有在ruby中使用正则表达式的有效文件?
目前,我的解决方案如下:
IP_ADDR_REGEX = %r{
\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
}x
当IP用空格分隔时,这很有效,例如它从文本192.168.1.1
中提取bla bla 192.168.1.1 bla
。但是,在这种情况下,它仍会提取192.168.1.1
:bla bla 192.168.1.1.1.1 bla
。
如何使它与这种情况不匹配?即当它是192.168.1.1.1.1
时,我的正则表达式不应该返回匹配。我找了很多关于这个问题的解决方案但找不到我想要的东西。我还试图通过最后只匹配空格来找出解决方案(因为\b
也匹配.
字符)但我无法使其工作。
感谢
答案 0 :(得分:5)
您应该将单词边界匹配器\b
更改为显式空格(并将其与正向前导匹配,因为您不希望它返回):
IP_ADDR_REGEX = %r{
(?<=\s|^)
(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]?)
(?=\s|$)
}x
main ▶ 'bla bla 192.168.1.1.1.1 bla'[IP_ADDR_REGEX]
#⇒ nil
main ▶ 'bla bla 192.168.1.1.1 bla'[IP_ADDR_REGEX]
#⇒ nil
main ▶ 'bla bla 192.168.1.1 bla'[IP_ADDR_REGEX]
#⇒ "192.168.1.1"
答案 1 :(得分:4)
如果类似IP的字符串前面有一个数字和一个点,或者后跟一个点和一个数字,你可以通过添加会使匹配失败的外观来解决它:
IP_ADDR_REGEX = %r{
\b # Word boundary
(?<!\d\.) # Negative lookbehind: no "X." before
(?: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 # Word boundary
(?!\.\d) # Negative lookahead: no ".X" after
}x
请注意,如果您只想将匹配限制为以空格分隔的子字符串,请使用
IP_ADDR_REGEX = %r{
(?<!\S) # Position not preceded with non-whitespace char
(?: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]?)
(?!\S) # Position not followed with non-whitespace char
}x
请注意,(?:...)
非捕获组可以更轻松地使用String#scan
方法从字符串中收集所有匹配项。