【问题标题】:Unable to match IP regex in JavaScript无法匹配 JavaScript 中的 IP 正则表达式
【发布时间】:2016-04-07 09:16:12
【问题描述】:

以下是我正在尝试在前端验证 IP 地址的代码,但不知何故,这个正则表达式不起作用 -

var patt = /[0-255]\.[0-255]\.[0-255]\.[0-255]/;
var str = "90.89.99.90";

if(str.match(patt))
  console.log("Valid IP");
else
  console.log("Invalid IP");

它应该输出 - 有效 IP

虽然这些类型的 IP 应该返回 - 无效 IP

“fd.45.67.90”、“256.67.67.89”、“@@.45.67.90”等

让我知道我在使用正则表达式时做错了什么。

【问题讨论】:

  • 你应该使用 str.test(patt) 而不是 str.match,因为 .match 返回匹配数组而不是 true / false。

标签: javascript regex


【解决方案1】:

正则表达式范围并不像您认为的那样。 [x-y] 范围包含从 xy 的所有 ascii 字符。

因此[0-255] 匹配从02(又名012)和5 或简而言之-[0125] 的字符。


要匹配从0255 的数字,您可以这样做:

\d\d?|1\d\d|2([0-4]\d|5[0-5])

想法:

  • \d\d? - 一位或两位数字
  • 1\d\d - 从 100199 的数字
  • 2[0-4]\d - 从200249 的数字。
  • 25[0-5] - 从 250255 的数字

要匹配整个 IP,您可以这样做:

^((\d\d?|1\d\d|2([0-4]\d|5[0-5]))\.){3}(\d\d?|1\d\d|2([0-4]\d|5[0-5]))$

【讨论】:

  • 我尝试了你的正则表达式,但它不起作用......我还需要在这里添加什么吗?
  • @TechSolvr,正则表达式将匹配单个数字 0 - 255,而不是 ip。我会更新我的答案。
  • 它不应该验证这个
  • @stribizhev 非常感谢!! ..你可以添加这个我也会支持你的答案:)
  • 我根据这个答案发布了我的 IP 匹配正则表达式的变体。
【解决方案2】:

[...] 表示“字符类”,意思是它列出了应该在那里匹配的字符;它匹配您列出的任何单个字符。因此,您的正则表达式正在检查每个段中是否存在 单个字符,它是 0、1、2 或 5 中的任何一个(0-2 给我们 0、1 和 2;然后 5 给我们 5,并且第二个 5 被忽略)。它应该检查数字(\d)和其中的 1-3 个({1,3}):

var patt = /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/;

您可能还需要^(输入开始)和$(输入结束),以便foo123.123.123.123bar 不匹配:

var patt = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/$;

当然,这不足以检查 IP 是否有效。它只是检查是否有预期的数字;它会很高兴地调用891.262.999.42 valid。

如果您想正确验证它(例如,数字在有效范围内,过滤掉无效的段组合等),您可以提取this comprehensive URL validation regex 的 IP 部分(因为 URL 可以包含 IP 地址,它涵盖了这一点)。值得庆幸的是,Diego 和其他作者对它进行了很好的评论,清楚地确定了哪些位做什么:

//
// Regular Expression for URL validation
//
// Author: Diego Perini
// Updated: 2010/12/05
// License: MIT
//
// Copyright (c) 2010-2013 Diego Perini (http://www.iport.it)
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
// the regular expression composed & commented
// could be easily tweaked for RFC compliance,
// it was expressly modified to fit & satisfy
// these test for an URL shortener:
//
//   http://mathiasbynens.be/demo/url-regex
//
// Notes on possible differences from a standard/generic validation:
//
// - utf-8 char class take in consideration the full Unicode range
// - TLDs have been made mandatory so single names like "localhost" fails
// - protocols have been restricted to ftp, http and https only as requested
//
// Changes:
//
// - IP address dotted notation validation, range: 1.0.0.0 - 223.255.255.255
//   first and last IP address of each class is considered invalid
//   (since they are broadcast/network addresses)
//
// - Added exclusion of private, reserved and/or local networks ranges
//
// - Made starting path slash optional (http://example.com?foo=bar)
//
// - Allow a dot (.) at the end of hostnames (http://example.com.)
//
// Compressed one-line versions:
//
// Javascript version
//
// /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i
//
// PHP version
//
// _^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]-*)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]-*)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$_iuS
//
var re_weburl = new RegExp(
  "^" +
    // protocol identifier
    "(?:(?:https?|ftp)://)" +
    // user:pass authentication
    "(?:\\S+(?::\\S*)?@)?" +
    "(?:" +
      // IP address exclusion
      // private & local networks
      "(?!(?:10|127)(?:\\.\\d{1,3}){3})" +
      "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" +
      "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" +
      // IP address dotted notation octets
      // excludes loopback network 0.0.0.0
      // excludes reserved space >= 224.0.0.0
      // excludes network & broacast addresses
      // (first & last IP address of each class)
      "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" +
      "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" +
      "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" +
    "|" +
      // host name
      "(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)" +
      // domain name
      "(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*" +
      // TLD identifier
      "(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))" +
      // TLD may end with dot
      "\\.?" +
    ")" +
    // port number
    "(?::\\d{2,5})?" +
    // resource path
    "(?:[/?#]\\S*)?" +
  "$", "i"
);

【讨论】:

    【解决方案3】:

    这是一个正则表达式变体(基于ndnanswer above),它将检查整个输入文本 是否为有效IP:

    ^(?:(?:\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]))$
    

    regex demo

    这是一个解决方案,可用于从较大的文本中提取有效 IP:

    \b(?:(?:\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]))\b
    

    another demo

    解释

    • ^ - 字符串开头(如果您不需要仅匹配字符串开头,则替换为 \b 单词边界)
    • (?:(?:\d{1,2}|1\d{2}|2(?:[0-4]\d|5[0-5]))\.){3} - 出现 3 次
      • (?:\d{1,2}|1\d{2}|2(?:[0-4]\d|5[0-5])) - 1 位或 2 位数字序列,或 1xx 数字 (1\d{2}) 或介于 200-255 之间的整数范围(感谢 2(?:[0-4]\d|5[0-5])
      • \. - 文字句号
    • (?:\d{1,2}|1\d{2}|2(?:[0-4]\d|5[0-5])) - 见上文(只是 IP 地址的最后一部分)
    • $ - 字符串结尾(如果您只需要整个单词匹配,请替换为 \b)。

    注意:在 JS 中,您可以使用文字符号来声明这些正则表达式,例如:

    /\b(?:(?:\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]))\b/g
    /^(?:(?:\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]))$/
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-26
      • 2022-08-17
      • 2023-03-18
      • 2014-02-16
      • 2011-11-29
      • 2012-09-22
      • 1970-01-01
      相关资源
      最近更新 更多