RegExp匹配的内容

时间:2016-01-14 11:59:56

标签: javascript regex node.js

我一直在尝试将以下内容从Python转换为node.js.它是一个简单的程序,使用正则表达式来检查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,所以我猜对了。我不明白另一场比赛的输出吗?我找不到它的含义

5 个答案:

答案 0 :(得分:1)

.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

答案 1 :(得分:1)

String.prototype.match()

  

如果正则表达式不包含g标志,则返回与RegExp.exec()相同的结果。返回的Array有一个额外的input属性,它包含已解析的原始字符串。此外,它还有一个index属性,表示字符串中匹配的从零开始的索引。

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

答案 2 :(得分:1)

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

在Javascript中,Array是真实的,null是假的。这意味着以下检查确实可以正确测试字符串是否为本地IP:

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

您在数组中看到的是原始字符串的不同部分,它们与正则表达式中的匹配组匹配。 null值是不存在的组的匹配,您有足够的。

但我认为你可以更进一步。如果您只想检查字符串是否与正则表达式匹配,我建议RegExp.prototype.test。此方法返回一个布尔值(true|false),因此您不必依赖于truthy或falsy-ness:

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

答案 3 :(得分:1)

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.'这是此字符串上正则表达式的匹配项。唯一一个
  • undefined是您的正则表达式中第一个组的匹配项:(^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()函数返回的匹配。

答案 4 :(得分:1)

您不需要使用匹配组,除非您想要捕获IP地址的匹配部分,但在您的情况下不需要。在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) != 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地址。如果要在应用程序的其他位置验证IP地址,这不是问题,但您可能希望将其收紧。

相关问题