单个字符串中的多个ip地址

时间:2016-12-07 07:08:03

标签: javascript regex

我有那种数据:

172.12.1.3;185.16.6.13;...

有时子掩码可能是:

172.12.1.3;185.16.6.13/32;172.12.1.4;...

所以我想使用正则表达式(在js中)确保每个ip地址都正确使用&#34 ;;"作为分隔符。

这应该不会太难,但即使进行了一些研究,我也只是设法做了这样的事情:

/^(((^|\.?)(1[0-9]{2}|[1-9][0-9]|[0-9]|2[0-4][0-9]|25[0-5])){4}(\;|$))*$/

顺便说一下,我知道我应该,但我并没有真正进入正则表达式...

有人可以帮我一把吗?

编辑:

所以我尝试过这样的事情:

var poolIp = v.split(";");

var ipAddress = /^(((^|\.?)(1[0-9]{2}|[1-9][0-9]|[0-9]|2[0-4][0-9]|25[0-5])){4}(\;|$))*$/;
var ret = true;
for (var i = 0; i < poolIp.length; i++) {
    var matches = ipAddress.exec(poolIp[i]);
    if (!matches) {
        ret = false;
    }
}
return ret;

它的方式更好,但带子掩码的IP地址无效,3位数的ip有效。

2 个答案:

答案 0 :(得分:2)

您可以使用以下函数来验证此类IP地址字符串。请注意,可以增强端口号验证,我只检查该值是否为数字。

function checkIsIPV4s(entry) {
  var ips = entry.split(';');       // Split into separate IPs
  for (var ip of ips) {
    var blocks = ip.split(/[.\/]/); // Split with dot and slash
    if(blocks.length === 5) {       // If there are 5 blocks,
      var last = blocks.pop();      //   remove the last one 
      if (!/^\d+$/.test(last)) {    //   and check if it is numeric
        return false;               //   if not - FALSE
      }
    }
    if(blocks.length === 4) {       // If block number is 4
      var res = blocks.every(function(block) { // check each part
        return parseInt(block,10) >=0 && parseInt(block,10) <= 255;
      });
      if (!res) {return false; }    // If any part is not in 0..255 - FALSE
    } else {  
      return false;                 // If block number is not 4 - FALSE
    }
  }
  return true;
}
var str = "172.12.1.3;185.16.6.13/32;172.12.1.4;255.255.255.255";
console.log(checkIsIPV4s(str));
str2 = "172.12.1.34444;185.16.6.13/32";
console.log(checkIsIPV4s(str2));

然而,有一种方法可以使用庞大且难以理解的正则表达式。添加它只是为了表明可以使用正则表达式进行:

/^(?:(?:\d{1,2}|1\d{2}|2(?:[0-4]\d|5[0-5]))\.){3}(?:\d{1,2}|1\d{2}|2(?:[0-4]\d|5[0-5]))(?:\/\d+)?(?:;(?:(?:\d{1,2}|1\d{2}|2(?:[0-4]\d|5[0-5]))\.){3}(?:\d{1,2}|1\d{2}|2(?:[0-4]\d|5[0-5]))(?:\/\d+)?)*$/

请参阅regex demo

模式匹配:

  • ^ - 字符串开头
  • (?:(?:\d{1,2}|1\d{2}|2(?:[0-4]\d|5[0-5]))\.){3}(?:\d{1,2}|1\d{2}|2(?:[0-4]\d|5[0-5]))(?:\/\d+)? - 具有可选端口号((?:\/\d+)?
  • 的单个IP模式(全部为(?:\/\d+)?
  • (?: - 非捕获组开始
    • ; - 分隔符
    • (?:(?:\d{1,2}|1\d{2}|2(?:[0-4]\d|5[0-5]))\.){3}(?:\d{1,2}|1\d{2}|2(?:[0-4]\d|5[0-5]))(?:\/\d+)? - 单一IP模式,与上述相同
  • )* - 出现0次或更多次非捕获组序列
  • $ - 字符串结束。

答案 1 :(得分:1)

这应该这样做:

var re = /^(;?[1-9][\d]{1,2}(\.[\d]{1,3}){3}(\/[\d]{1,3})?)+$/
re.test('172.12.1.3;185.16.6.13/32;172.12.1.4') // true
re.test('172.12.1.3;185.16.6.13/32;172.12.1') // false
re.test('072.12.1.3;185.16.6.13/32;172.12.1.4') // false

或将它们分开:

var re = /^[1-9][\d]{1,2}(\.[\d]{1,3}){3}(\/[\d]{1,3})?$/
var ip1 = '172.12.1.3;185.16.6.13/32;172.12.1.4'.split(';');
var ip2 = '172.12.1.3;185.16.6.13/32;172.12.1'.split(';');
var ip3 = '072.12.1.3;185.16.6.13/32;172.12.1.4'.split(';');
ip1.every((ip) => re.test(ip));
ip2.every((ip) => re.test(ip));
ip3.every((ip) => re.test(ip));

您可以使用http://regexr.com/来测试正则表达式,并阅读Array.every here.

相关问题