【问题标题】:Contents of a RegExp matchRegExp 匹配的内容
【发布时间】:2016-04-19 18:01:04
【问题描述】:

我一直在尝试将以下内容从 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

在我看来它似乎有效(甚至不确定)。应该公开的两个 IP 返回null,所以我猜这是对的。我不明白另一场比赛的输出吗?一直没弄明白是什么意思

【问题讨论】:

  • .match() 为您提供字符串中可能的匹配数。也许您正在寻找的是 .test() 方法。

标签: javascript regex node.js


【解决方案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 地址不是问题,但您可能需要加强它。

【讨论】:

    【解决方案2】:

    String.prototype.match():

    如果正则表达式不包含 g 标志,则返回与 RegExp.exec() 相同的结果。返回的 Array 有一个额外的输入属性,其中包含已解析的原始字符串。另外,它还有一个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
    

    【讨论】:

      【解决方案3】:
      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】:

        您正在使用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),因此您不必依赖真假:

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

        【讨论】:

          【解决方案5】:

          .match() 为您提供字符串中可能的匹配数。也许您正在寻找的是 .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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-02-11
            • 1970-01-01
            • 1970-01-01
            • 2011-08-03
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多