我似乎无法绕过这个。 我有一个正则表达式,检查字符串是否包含有效的CIDR表示法地址。
(((?:25[012345]|2[0-4]\d|1?\d\d?)\.){3}(?:25[012345]|2[0-4]\d|1?\d\d?))(?:\/([1-9]|[1-2][0-9]|3[0-2]))(?![.\d])
这个东西适用于Perl,PHP,Javascript,并且匹配x.x.x.x/8
到y.y.y.y/32
。
我试图将\d
更改为[[:digit:]]
并更改为\\d
:(
用于测试的测试脚本:
#!/bin/bash
if [ "$1" = "" ]
then
echo "Usage: $( basename $0) 123.456.789.0/12"
exit
fi
REGEX1='(((?:25[012345]|2[0-4]\d|1?\d\d?)\.){3}(?:25[012345]|2[0-4]\d|1?\d\d?))(?:\/([1-9]|[1-2][0-9]|3[0-2]))(?![.\d])'
REGEX2='(((?:25[012345]|2[0-4]\\d|1?\\d\\d?)\.){3}(?:25[012345]|2[0-4]\\d|1?\\d\\d?))(?:\\/([1-9]|[1-2][0-9]|3[0-2]))(?![.\\d])'
REGEX3='(((?:25[012345]|2[0-4][[:digit:]]|1?[[:digit:]][[:digit:]]?)\\.){3}(?:25[012345]|2[0-4][[:digit:]]|1?[[:digit:]][[:digit:]]?))(?:\\/([1-9]|[1-2][0-9]|3[0-2]))(?![.[[:digit:]]])'
REGEX=$REGEX3
if [[ $1 =~ $REGEX ]]
then
echo "$1 OK!"
else
echo "$1 Not OK! $REGEX"
fi
有什么想法从哪里开始?
更新。添加了工作脚本:
#!/bin/bash
if [ "$1" = "" ]
then
echo "Usage: $( basename $0) 123.456.789.0/12"
exit
fi
REGEX='(((25[0-5]|2[0-4][0-9]|1?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|1?[0-9][0-9]?))(\/([8-9]|[1-2][0-9]|3[0-2]))([^0-9.]|$)'
if [[ $1 =~ $REGEX ]]
then
echo "$1 OK!"
else
echo "$1 Not OK!"
fi
if echo $1 | grep -Pq $REGEX
then
echo "grep $1 OK!"
else
echo "grep $1 Not OK!"
fi
答案 0 :(得分:3)
成功的最短途径是GNU grep,它也支持PCRE:
if echo $CIDR | grep -qP "$REGEX"
then
echo "$CIDR OK!"
exit 0
else
echo "$CIDR NOT OK!"
exit 1
fi
grep' s -q
使其保持沉默并依赖退出代码来确定成功。 -P
是PCRE。
但我应该指出,你的正则表达式并不完全匹配某个有效的CIDR范围;相反,您匹配有效的IP地址,后跟斜杠和数字 n ∈1-32。对CIDR范围的另一个要求是地址的 32-n 低位为零,例如:
IFS="./" read -r ip1 ip2 ip3 ip4 N <<< $CIDR
ip=$(($ip1 * 256 ** 3 + $ip2 * 256 ** 2 + $ip3 * 256 + $ip4))
if [ $(($ip % 2**(32-$N))) = 0 ]
then
echo "$CIDR OK!"
exit 0
else
echo "$CIDR NOT OK!"
exit 1
fi
用例如测试127.0.0.0/24
,127.1.0.0
,127.1.1.0/24
。
或更奇怪的范围:10.10.10.8/29
,127.0.0.0/8
,127.3.0.0/10
,192.168.248.0/21
。
答案 1 :(得分:0)
Simon的解决方案很优雅。 :)
我不是复杂正则表达式的忠实粉丝来验证具有应该以其他方式解释的含义的东西,所以或者,如果您更喜欢使用字符串操作而不是数学,我不久前写了下面这个函数:
valid_cidr_network() {
local ip="${1%/*}" # strip bits to leave ip address
local bits="${1#*/}" # strip ip address to leave bits
local IFS=.; local -a a=($ip)
# Sanity checks (only simple regexes)
[[ $ip =~ ^[0-9]+(\.[0-9]+){3}$ ]] || return 1
[[ $bits =~ ^[0-9]+$ ]] || return 1
[[ $bits -gt 32 ]] || return 1
# Create an array of 8-digit binary numbers from 0 to 255
local -a binary=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})
local binip=""
# Test and append values of quads
for quad in {0..3}; do
[[ "${a[$quad]}" -gt 255 ]] && return 1
printf -v binip '%s%s' "$binip" "${binary[${a[$quad]}]}"
done
# Fail if any bits are set in the host portion
[[ ${binip:$bits} = *1* ]] && return 1
return 0
}
此函数以二进制形式汇编IP地址,如果在IP地址的主机部分设置了任何&#34; 1&#34;则失败。