我正在尝试通过正则表达式来匹配在traceroute输出中找到的IP地址。我不会尝试验证它们,因为假设traceroute是有效的(即不输出像999.999.999.999这样的东西)是足够安全的。我正在尝试以下正则表达式:
([0-9]{1,3}.?){4}我正在regex101中测试它,它确实验证了一个IP地址。然而,当我尝试
echo '192.168.1.1 foobar' | grep '([0-9]{1,3}.?){4}' 我什么也得不到。我遗漏了什么?
发布于 2017-06-20 21:49:22
您使用了POSIX模式,但是没有通过-E选项让grep使用POSIX风格。因此,grep改用POSIX BRE,您需要转义{n,m}量词和(...),以便将它们解析为特殊的正则表达式运算符。
注您需要对.进行转义,以便它只能与文字点匹配。
要使您的模式以您想要的方式与grep一起工作,您可以使用:
grep -E '([0-9]{1,3}\.?){4}' # POSIX ERE
grep '\([0-9]\{1,3\}\.\?\)\{4\}' # POSIX BRE version of the same regex请参见online demo。
然而,这个正则表达式也将匹配几个数字的字符串,因为.是可选的。
您可以通过如下方式展开模式来解决此问题
grep -E '[0-9]{1,3}(\.[0-9]{1,3}){3}' # POSIX ERE
grep '[0-9]\{1,3\}\(\.[0-9]\{1,3\}\)\{3\}' # POSIX BRE参见another demo。
基本上,它匹配:
[0-9]{1,3} -1到3次出现任何ASCII digit(\.[0-9]{1,3}){3} -3出现:\. -a文字.[0-9]{1,3} -1到3次任何ASCII digit要确保仅匹配有效的IP,您可能需要使用more precise IP matching regex
grep -E '\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]?)){3}\b' # POSIX ERE您可以进一步调整它与单词边界(可以是\< / \>或\b),等等。
将-o选项与grep:grep -oE 'ERE_pattern' file / grep -o 'BRE_pattern' file一起使用来提取IP。
发布于 2018-07-30 07:11:55
要进行更有效的验证,最好使用函数而不是简单的正则表达式匹配:
#!/bin/bash
is_valid_ip() {
local arr element
IFS=. read -r -a arr <<< "$1" # convert ip string to array
[[ ${#arr[@]} != 4 ]] && return 1 # doesn't have four parts
for element in "${arr[@]}"; do
[[ $element =~ ^[0-9]+$ ]] || return 1 # non numeric characters found
[[ $element =~ ^0[1-9]+$ ]] || return 1 # 0 not allowed in leading position if followed by other digits, to prevent it from being interpreted as on octal number
((element < 0 || element > 255)) && return 1 # number out of range
done
return 0
}您可以像这样调用它:
while read -r ip; do
is_valid_ip "$ip" && printf '%s\n' "$ip"
done < <(your command that extracts ip address like strings)相关信息:
https://stackoverflow.com/questions/44654809
复制相似问题