我正在尝试通过正则表达式匹配traceroute
输出中找到的IP地址。我没有尝试验证它们,因为它足够安全,假设traceroute
有效(即没有输出类似999.999.999.999
的内容。我正在尝试以下正则表达式:\ n \ n
([0-9]{1,3}.?){4}
我在regex101进行测试,确实验证了IP地址。但是,当我尝试
时echo '192.168.1.1 foobar' | grep '([0-9]{1,3}.?){4}'
我一无所获。我错过了什么?
答案 0 :(得分:6)
您使用了POSIX ERE模式,但没有通过-E
选项让grep
使用POSIX ERE风格。因此,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}
- 任意ASCII数字出现1到3次(\.[0-9]{1,3}){3}
- 出现3次:
\.
- 文字.
[0-9]{1,3}
- 任意ASCII数字出现1到3次要确保只匹配有效的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
请参阅this online demo。
您可以使用字边界进一步调整它(可以是\<
/ \>
或\b
)等。
提取IP 使用-o
选项与grep
:grep -oE 'ERE_pattern' file
/ grep -o 'BRE_pattern' file
。
答案 1 :(得分:1)
要进行更有效的验证,最好使用函数而不是简单的正则表达式匹配:
#!/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)
相关: