问题在于,我允许用户输入由分号分隔的IP白名单或IP列表或IP范围。
所以他们可以把
74.122.31.233; 76.233.12.222 - 80.788.888.111; 72.203.44.209
74.122.31.233; 76.233.12.222; 72.203.44.209
74.122.31.233 - 76.233.12.222; 72.203.44.209
74.122.31.233-76.233.12.222; 72.203.44.209
74.122.31.233-76.233.12.222;72.203.44.209
他们可以选择使用空格或不使用空格之间和分号前后的空格。
因此,他们可以将分号或分号分隔的IP地址用分号或IP地址分隔,IP分区用分号分隔。
我是常规表达的新手。有没有人知道正确的方法来验证他们是否正确输入IP白名单以遵守上述规则?
感谢。
答案 0 :(得分:5)
我不相信正则表达式在这种情况下是必要的甚至是有用的,特别是当PHP有filter_var()
时:
function isValid($ranges) {
// remove all spaces
$ranges = str_replace(' ', '', $ranges);
// iterate over individual ranges and IP addresses
foreach(explode(';', $ranges) as $range) {
// single address
if(strpos($range, '-') === false) {
if(!filter_var($range, FILTER_VALIDATE_IP)) {
return false;
}
}
// range
else {
$addresses = explode('-', $range, 3);
if(count($addresses) != 2) {
return false;
}
if(!filter_var($addresses[0], FILTER_VALIDATE_IP) || !filter_var($addresses[1], FILTER_VALIDATE_IP)) {
return false;
}
}
}
return true;
}
$tests = array(
'74.122.31.233; 76.233.12.222 - 80.788.888.111; 72.203.44.209',
'74.122.31.233; 76.233.12.222; 72.203.44.209',
'74.122.31.233 - 76.233.12.222; 72.203.44.209',
'74.122.31.233-76.233.12.222; 72.203.44.209',
'74.122.31.233-76.233.12.222;72.203.44.209');
foreach($tests as $test) {
echo $test;
echo isValid($test) ? ' is valid' : ' is invalid';
echo "\n";
}
输出:
74.122.31.233; 76.233.12.222 - 80.788.888.111; 72.203.44.209 is invalid // 80.788.888.111 is an invalid IP address
74.122.31.233; 76.233.12.222; 72.203.44.209 is valid
74.122.31.233 - 76.233.12.222; 72.203.44.209 is valid
74.122.31.233-76.233.12.222; 72.203.44.209 is valid
74.122.31.233-76.233.12.222;72.203.44.209 is valid
答案 1 :(得分:2)
按;
分解它们,然后trim
数组值以删除空格。这样,您可以确保同等对待用户输入的间隔版本和非间距版本。
$parts = explode(';', $text);
$parts = array_map('trim', $parts);
//or $parts = array_map('trim', explode(';', $text));
//check if IP is valid
要验证IP,您不需要正则表达式。 PHP已经有一个内置函数filter_var()
,它完全符合您的要求。
$parts = array_map('trim', explode(';', $text));
foreach ($parts as $ip) {
if(strpos($ip, '-')) {
list($range1, $range2) = explode('-', $ip);
// validate IP range here
}
elseif (filter_var($ip, FILTER_VALIDATE_IP) ) {
echo "$ip is valid<br/>";
}
}
这应该让你开始。
答案 2 :(得分:2)
不要试图将所有内容都塞进一个正则表达式中。我知道你在想,经典菜鸟的错误。
$input = preg_replace('/\s/', '', $input);
$in_arr = explode(';', $input);
if( preg_match('/-/', $in_arr[index]) )
然后explode('-', $in_arr[index]);
,然后像范围一样处理ip2long()
。
80.788.888.111
这样的无效地址输入ip2long()
,则会返回false,不需要复杂的正则表达式。ip2long()
使方式更容易比较IP地址,'123.123.123.3' > '123.123.123.10'
[字符串比较,错误],但ip2long('123.123.123.3') < ip2long('123.123.123.10')
[整数比较,不错] 答案 3 :(得分:1)
这是一个简单的功能:
function validateInput($s) {
foreach (explode(';', $s) as $v) {
$v = array_map('trim', explode('-', $v));
if (count($v) > 2) return false;
$valid = true;
foreach ($v as $ip) $valid = $valid && filter_var($ip, FILTER_VALIDATE_IP);
if (!$valid) return false;
}
return true;
}
使用示例:
$inputs = [
'74.122.31.233; 76.233.12.222 - 80.788.888.111; 72.203.44.209',
'74.122.31.233; 76.233.12.222; 72.203.44.209',
'74.122.31.233-76.233.12.222;72.203.44.209',
'274.122.31.233-76.233.12.222',
'74.122.31.233-76.233.12.222-77.233.12.222',
];
foreach ($inputs as $input) {
echo (validateInput($input) ? 'TRUE ' : 'FALSE') . " : $input\n";
}
输出:
FALSE : 74.122.31.233; 76.233.12.222 - 80.788.888.111; 72.203.44.209
TRUE : 74.122.31.233; 76.233.12.222; 72.203.44.209
TRUE : 74.122.31.233-76.233.12.222;72.203.44.209
FALSE : 274.122.31.233-76.233.12.222
FALSE : 74.122.31.233-76.233.12.222-77.233.12.222