我试图匹配的字符串是一个 IP 地址,我在网上看到了很多例子。然而,我似乎遗漏了一些可能与正则表达式约定之间的差异有关或无关的东西。 (PCRE,呃,??)
为了将其分解到我所缺少的点,这是我试图匹配的部分 IP 地址:
ip="255.255."
这是一个尝试匹配上面 ip 的正则表达式:
^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?\.){2}
这是 bash 所以我有这个来比较:
[[ ${ip} =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?\.){2} ]] && echo "ok"
唉,这不匹配。
据我所知,我可以逃脱。因为我希望它匹配一个点字符,而不仅仅是任何字符。 (据我所知,. 在正则表达式中代表什么。)
这是当我删除点之前的转义来说明上述语句时发生的情况:
# ip="255.255."
# [[ ${ip} =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.){2} ]] && echo "ok"
ok
# ip="255X255Y"
# [[ ${ip} =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9] [0-9]?.){2} ]] && echo "ok"
ok
在这种情况下,匹配(部分)ip 是不正确的。
为什么它不匹配这个:
# ip="255.255."
# [[ ${ip} =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?\.){2} ]] && echo "ok" || echo "nope"
nope
有两组,每组都是“255”。这部分匹配得很好,如下所示:
# ip="255."
# [[ ${ip} =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?\.) ]] && echo "ok" || echo "nope"
ok
编辑:一些可能解决我的问题的额外信息:
刚刚注意到以下几点:
# ip="172.15.11.10"
# [[ ${ip} =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?\.){2} ]] && echo "ok" || echo "nope"
ok
# ip="172.15."
# [[ ${ip} =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?\.){2} ]] && echo "ok" || echo "nope"
ok
当进行以下分组时:
# [[ ${ip} =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?\.){2} ]] && echo "ok" || echo "nope"
nope
# [[ ${ip} =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){2} ]] && echo "ok" || echo "nope"
ok
那么将“数字”部分分组在分隔符“点”前面可以解决问题吗?
# ip="255.255."
# [[ ${ip} =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){2} ]] && echo "ok" || echo "nope"
ok
我倾向于认为这可以解决问题,但我还不明白为什么。
编辑:IP 地址的完整正则表达式如下:
^((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]?)
这与杰夫在下面的回答中提到的相同。
答案1
括号放错地方了。
在失败的正则表达式中,您将八位位组的可能性与交替组合在一起:
^(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]?\.
请注意该句号是如何成为第三种可能的交替的一部分的。这会强制正则表达式匹配初始的255
,使接下来的句点不匹配。
您希望重复八位位组和句点,因此将正则表达式分组如下:
^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){2}
或者像这样:
^((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 地址单独出现在一行中。如果您不关心 IP 地址在行中显示的位置,请删除前导 ( ^
) 和尾随 ( $
) 锚点。
在 Linux 上,为了在测试中提供视觉帮助,您可以使用grep --color=always -E ...
,例如:
$ ip=jeff-255.255.255.255-foo
$ echo "$ip" | grep --color=always -E '((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]?)'
杰夫-255.255.255.255-foo
...其中255.255.255.255
以颜色显示。