RegExp匹配的内容

我一直在试图从Python转换为node.js. 这是一个简单的程序,使用正则expression式来检查IP地址是公共还是私有:

import re def is_private_ip(ip): """ Returns `True` if the `ip` parameter is a private network address. """ c = re.compile('(^127\.0\.0\.1)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)') if c.match(ip): return True return False print is_private_ip('192.168.0.1') # True print is_private_ip('8.8.8.8') # False print is_private_ip('109.231.231.221') # False 

我用Javascript来实现它,就像这样:

 var localIp = new RegExp(/(^127\.0\.0\.1)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)/); console.log('192.168.0.1'.match(localIp)); console.log('8.8.8.8'.match(localIp)); console.log('109.231.231.221'.match(localIp)); 

这给了我以下输出:

 [ '192.168.', undefined, undefined, undefined, undefined, undefined, '192.168.', index: 0, input: '192.168.0.1' ] null null 

在我看来,它似乎有效(甚至不知道tbh)。 应该公开的两个IP地址返回null所以我猜测这是正确的。 我不明白其他比赛的输出? 我一直无法找出它的含义

 var localIp = new RegExp(/(^127\.0\.0\.1)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)/); 

的console.log('192.168.0.1'.match(localIp));

给你输出:

 [ '192.168.', undefined, undefined, undefined, undefined, undefined, '192.168.'] 

这意味着:

  • '192.168.' 那就是这个string上的正则expression式的匹配。 唯一的
  • undefined是正则expression式中第一个组的匹配: (^127\.0\.0\.1)
  • undefined的组: (^10\.)
  • undefined的组: (^172\.1[6-9]\.)
  • undefined的组: (^172\.2[0-9]\.)
  • undefined的组: (^172\.3[0-1]\.)
  • '192.168.' 对于该组: (^192\.168\.)

多数民众赞成在括号,每一个给一个匹配(或未定义),再加上match()函数返回的match()

.match()给你的string中可能的匹配数量。 也许你正在寻找的是.test()方法。

你需要像这样修改代码:

 var localIp = new RegExp(/(^127\.0\.0\.1)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)/); console.log(localIp.test('192.168.0.1')); console.log(localIp.test('8.8.8.8')); console.log(localIp.test('109.231.231.221')); 

你可以在这里参考关于匹配方法的更多细节: https : //developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/match

您正在使用String.prototype.match – 方法。 根据文档,它返回“包含匹配结果的Array ”,如果没有匹配,则返回null

在Javascript中,一个Array是真的, null是虚的。 这意味着下面的检查确实可以正确testing一个string是否是本地IP:

 if(someIpString.match(localIp)) { // it is a local IP } else { // it is not a local IP } 

在数组中看到的是原始string的不同部分,这些部分由正则expression式中的匹配组匹配。 null值是不存在的组的匹配,你有很多。

但我认为你可以更进一步。 如果你想简单地检查一个string是否与正则expression式匹配,我会推荐RegExp.prototype.test 。 这个方法返回一个布尔值( true|false ),所以你不必依赖于真实性或者错误:

 if(localIp.test(someIpString)) { // it is a local IP } else { // it is not a local IP } 

String.prototype.match() :

如果正则expression式不包含g标志,则返回与RegExp.exec()相同的结果。 返回的数组有一个额外的input属性,其中包含被parsing的原始string。 另外,它还有一个索引属性,它表示string中匹配的从零开始的索引。

RegExp.prototype.exec() :

返回的数组具有匹配的文本作为第一个项目,然后匹配的每个捕获括号中的一个项目包含捕获的文本。

如果匹配失败,则exec()方法返回null。

也许你想使用RegExp.prototype.test()来代替:

 var localIp = new RegExp(/(^127\.0\.0\.1)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)/); console.log(localIp.test('192.168.0.1')); // => true console.log(localIp.test('8.8.8.8')); // => false console.log(localIp.test('109.231.231.221')); // => false 

你不需要使用匹配组,除非你想捕获匹配的IP地址部分,但这不是必要的。 在Javascript中,你可以使用这个正则expression式(注意不匹配组):

 var localIp = new RegExp(/^127\.0\.0\.1|^10\.|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-1]\.|^192\.168\./); 

然后像这样使用它:

 console.log('192.168.0.1'.match(localIp) != null); console.log('8.8.8.8'.match(localIp) != null); console.log('109.231.231.221'.match(localIp) != null); 

或者,更好的办法是使用RegEx.test()

 console.log(localIp.test('192.168.0.1')); 

对于Python也是如此,不需要匹配组。

另外值得注意的是,你的模式将匹配无效的IP地址,例如10.bad.ip.address将被检测为私有IP地址。 如果正在validation应用程序中其他地方的IP地址,则不是问题,但您可能需要将其encryption。