【问题标题】:javascript regular expression to check for IP addresses用于检查 IP 地址的 javascript 正则表达式
【发布时间】:2011-05-26 12:36:36
【问题描述】:

我有几个 IP 地址,例如:

  1. 115.42.150.37
  2. 115.42.150.38
  3. 115.42.150.50

如果我想搜索所有 3 个 ip 地址,我应该写什么类型的正则表达式?例如,如果我这样做115.42.150.*(我将能够搜索所有 3 个 IP 地址)

我现在可以做的是:/[0-9]{1-3}\.[0-9]{1-3}\.[0-9]{1-3}\.[0-9]{1-3}/,但它似乎无法正常工作。

谢谢。

【问题讨论】:

  • How to evaluate an IP? 的可能重复项
  • Bill The Lizard 的欺骗链接有一个很好的正则表达式
  • 我同意 Pekka 的观点,链接的问题应该完全满足您的要求。
  • 请使用我在这篇文章中的回答:stackoverflow.com/questions/23483855/…,这是迄今为止最准确的回答。

标签: javascript regex string string-matching


【解决方案1】:

可能会迟到,但有人可以试试:

有效 IP 地址示例

115.42.150.37
192.168.0.1
110.234.52.124

无效 IP 地址示例

210.110 – must have 4 octets
255 – must have 4 octets
y.y.y.y – only digits are allowed
255.0.0.y – only digits are allowed
666.10.10.20 – octet number must be between [0-255]
4444.11.11.11 – octet number must be between [0-255]
33.3333.33.3 – octet number must be between [0-255]

用于验证 IP 地址的 JavaScript 代码

function ValidateIPaddress(ipaddress) {  
  if (/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipaddress)) {  
    return (true)  
  }  
  alert("You have entered an invalid IP address!")  
  return (false)  
}  

【讨论】:

  • 效果很好,感谢您提供完整的功能以及将/不会通过的示例。
  • 你的正则表达式是我唯一能通过测试的。谢谢!
  • 很高兴我能帮上忙。享受编码!
  • @ErickBest 答案的可视化:jex.im/regulex/…
  • 您的解决方案不应允许 '012.012.012.012'
【解决方案2】:

试试这个,它是一个较短的版本:

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

解释:

^ start of string
  (?!0)         Assume IP cannot start with 0
  (?!.*\.$)     Make sure string does not end with a dot
  (
    (
    1?\d?\d|   A single digit, two digits, or 100-199
    25[0-5]|   The numbers 250-255
    2[0-4]\d   The numbers 200-249
    )
  \.|$ the number must be followed by either a dot or end-of-string - to match the last number
  ){4}         Expect exactly four of these
$ end of string

浏览器控制台的单元测试:

var rx=/^(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4}$/;
var valid=['1.2.3.4','11.11.11.11','123.123.123.123','255.250.249.0','1.12.123.255','127.0.0.1','1.0.0.0'];
var invalid=['0.1.1.1','01.1.1.1','012.1.1.1','1.2.3.4.','1.2.3\n4','1.2.3.4\n','259.0.0.1','123.','1.2.3.4.5','.1.2.3.4','1,2,3,4','1.2.333.4','1.299.3.4'];
valid.forEach(function(s){if (!rx.test(s))console.log('bad valid: '+s);});
invalid.forEach(function(s){if (rx.test(s)) console.log('bad invalid: '+s);});

【讨论】:

  • 0.0.0.0 被认为是有效的
  • 在这种情况下,您可以省略负面预测(?!0)
  • 允许子网怎么样?体育:192.168.1.10/24
  • @migueloop 我没试过:^(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4}(\/\d+)?$
  • 我发现这个正则表达式将涵盖 ips 和子网。并确保它不会在每个块中允许前导 0。 /^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25 [0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5 ]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[ 0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\/([1-2][0-9]|3 [0-2]|[0-9]))?$/
【解决方案3】:

如果您使用的是 nodejs,请尝试:

require('net').isIP('10.0.0.1')

文档net.isIP()

【讨论】:

  • 我喜欢这个。这是最好的,尽管从技术上讲,它可能无法准确回答问题。易于使用且易于阅读。非常感谢!
  • 提取了 isIP() stackoverflow.com/a/68104187/9387542987654322@中使用的正则表达式
【解决方案4】:

你得到的正则表达式已经有几个问题了:

首先,它包含点。在正则表达式中,点表示“匹配任何字符”,您只需要匹配一个实际的点。为此,您需要对其进行转义,因此请在点前添加一个反斜杠。

其次,您要匹配每个部分中的任意三位数字。这意味着您将匹配 0 到 999 之间的任何数字,这显然包含大量无效的 IP 地址数字。

这可以通过使数字匹配更复杂来解决;这个网站上还有其他答案解释了如何做到这一点,但坦率地说,这不值得付出努力——在我看来,你最好用点分割字符串,然后将四个块验证为数字整数范围——即:

if(block >= 0 && block <= 255) {....}

希望对您有所帮助。

【讨论】:

  • 恕我直言,这是一个很好的答案。不尝试对正则表达式做太多通常是一个好习惯。将此答案与其他答案进行比较,并考虑哪一个产生的代码最易读/最直观。更易读的代码需要更少的时间来理解并且更不容易出错。
  • 挑剔:不应该是block &gt;= 0 吗?
  • @DaveYarwood:IP 地址不能大于 255。
  • 对,我的意思是不应该是&gt;= 而不是&gt;?因为 0 是一个有效的区块值。
  • 不错的解决方案,但是“000”块呢?它们是有效的 IP 块吗? (例如:000.000.000.000)
【解决方案5】:

不要编写自己的正则表达式或复制粘贴!您可能不会涵盖所有边缘 ceses(IPv6,还有八进制 IP 等)。使用is-ip package from npm

var isIp = require('is-ip');

isIp('192.168.0.1');

isIp('1:2:3:4:5:6:7:8');

将返回一个布尔值。

反对者:想解释一下为什么使用积极维护的库比从网站复制粘贴更好吗?

【讨论】:

  • OP 要求提供有效的 JS 解决方案。你只是假设 npm 可用。
  • @masi npm 哪里不可用?
  • @mikemaccana,在浏览器中
  • @elshev npm 多年来一直是 Web 浏览器最常见的软件包来源。早在 2012 年使用 gulp+browserify,然后在 2015 年使用 webpack,现在使用 rollup。
  • @rotem 我已按要求添加了链接。
【解决方案6】:

试试这个。来源来自here

"\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b"

【讨论】:

  • /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[ 0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0 -9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9] [0-9]?)$/.test('10.10.10.10')
【解决方案7】:

如果您想要在现代浏览器中比 ipv4 的正则表达式更具可读性,您可以使用

function checkIsIPV4(entry) {
  var blocks = entry.split(".");
  if(blocks.length === 4) {
    return blocks.every(function(block) {
      return parseInt(block,10) >=0 && parseInt(block,10) <= 255;
    });
  }
  return false;
}

【讨论】:

  • IP 200sd.100f.85.200(V)(或任何带有字母的)在您的函数中返回true。只需检查每个块上是否有!isNaN(block) 以避免这种情况。不错的功能顺便说一句。 return !isNaN(block) &amp;&amp; parseInt(block,10) &gt;=0 &amp;&amp; parseInt(block,10) &lt;= 255;
  • 我觉得功能应该实现为:function isIPv4Address(entry) { var blocks = entry.split("."); if(blocks.length === 4) { return blocks.every(function(block) { const value = parseInt(block, 10); if(value &gt;= 0 &amp;&amp; value &lt;= 255){ var i = block.length; while (i--) { if(block[i] &lt; '0' || block[i] &gt; '9'){ return false; } } return true; } }); } return false; }
  • 前导零无效(“123.045.067.089”应返回 false),并且您的解决方案允许前导零,但它不正确。
【解决方案8】:

以下解决方案不接受填充零

这是验证 IP 地址的最简单方法,让我们分解一下:

事实:一个有效的IP地址有4 octets,每个八位字节可以是0 - 255之间的一个数字

匹配0 - 255之间任意值的正则表达式分解

  • 25[0-5] 匹配 250 - 255
  • 2[0-4][0-9] 匹配 200 - 249
  • 1[0-9][0-9] 匹配 100 - 199
  • [1-9][0-9]? 匹配 1 - 99
  • 0 匹配 0
const octet = '(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)';

注意:当使用new RegExp 时,你应该使用\\. 而不是\.,因为字符串会被转义两次。

function isValidIP(str) {
  const octet = '(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)';
  const regex = new RegExp(`^${octet}\\.${octet}\\.${octet}\\.${octet}$`);
  return regex.test(str);
}

【讨论】:

  • 并非所有 IP 地址都有 4 个八位字节。
【解决方案9】:

一个简短的正则表达式:^(?:(?:^|\.)(?:2(?:5[0-5]|[0-4]\d)|1?\d?\d)){4}$

示例

const isValidIp = value => (/^(?:(?:^|\.)(?:2(?:5[0-5]|[0-4]\d)|1?\d?\d)){4}$/.test(value) ? true : false);


// valid
console.log("isValidIp('0.0.0.0') ? ", isValidIp('0.0.0.0'));
console.log("isValidIp('115.42.150.37') ? ", isValidIp('115.42.150.37'));
console.log("isValidIp('192.168.0.1') ? ", isValidIp('192.168.0.1'));
console.log("isValidIp('110.234.52.124' ? ", isValidIp('110.234.52.124'));
console.log("isValidIp('115.42.150.37') ? ", isValidIp('115.42.150.37'));
console.log("isValidIp('115.42.150.38') ? ", isValidIp('115.42.150.38'));
console.log("isValidIp('115.42.150.50') ? ", isValidIp('115.42.150.50'));

// Invalid
console.log("isValidIp('210.110') ? ", isValidIp('210.110'));
console.log("isValidIp('255') ? ", isValidIp('255'));
console.log("isValidIp('y.y.y.y' ? ", isValidIp('y.y.y.y'));
console.log(" isValidIp('255.0.0.y') ? ", isValidIp('255.0.0.y'));
console.log("isValidIp('666.10.10.20') ? ", isValidIp('666.10.10.20'));
console.log("isValidIp('4444.11.11.11') ? ", isValidIp('4444.11.11.11'));
console.log("isValidIp('33.3333.33.3') ? ", isValidIp('33.3333.33.3'));

【讨论】:

    【解决方案10】:
    /^(?!.*\.$)((?!0\d)(1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4}$/
    

    完全归功于oriadam。我会在他/她的回答下方发表评论,建议我做出双零更改,但我在这里还没有足够的声誉......

    改变

    【讨论】:

      【解决方案11】:

      简单方法

      const invalidIp = ipAddress
         .split(".")
         .map(ip => Number(ip) >= 0 && Number(ip) <= 255)
         .includes(false);
      
      if(invalidIp){
       // IP address is invalid
       // throw error here
      }
      

      【讨论】:

        【解决方案12】:

        IP地址格式的正则表达式:

        /^(\d\d?)|(1\d\d)|(0\d\d)|(2[0-4]\d)|(2[0-5])\.(\d\d?)|(1\d\d)|(0\d\d)|(2[0-4]\d)|(2[0-5])\.(\d\d?)|(1\d\d)|(0\d\d)|(2[0-4]\d)|(2[0-5])$/;
        

        【讨论】:

          【解决方案13】:

          如果你编写了正确的代码,你只需要这个非常简单的正则表达式:/\d{1,3}/

          function isIP(ip) {
              let arrIp = ip.split(".");
              if (arrIp.length !== 4) return "Invalid IP";
              let re = /\d{1,3}/;
              for (let oct of arrIp) {
                  if (oct.match(re) === null) return "Invalid IP"
                  if (Number(oct) < 0 || Number(oct) > 255)
                      return "Invalid IP";
          }
              return "Valid IP";
          }
          

          但实际上,完全不使用任何正则表达式可以得到更简单的代码:

          function isIp(ip) {
              var arrIp = ip.split(".");
              if (arrIp.length !== 4) return "Invalid IP";
              for (let oct of arrIp) {
                  if ( isNaN(oct) || Number(oct) < 0 || Number(oct) > 255)
                      return "Invalid IP";
          }
              return "Valid IP";
          }
          

          【讨论】:

          • 如果ipundefined 或者如果它是一个整数将失败。
          【解决方案14】:

          投一个后期的贡献:

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

          在我检查的答案中,它们的验证要么更长,要么不完整。根据我的经验,更长的时间意味着更难被忽视,因此更容易出错。出于同样的原因,我喜欢避免重复类似的模式。

          当然,主要部分是对数字的测试 - 0 到 255,但还要确保它不允许初始零(除非它是单个数字):

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

          三种交替 - 一种用于 sub 100:[1-9]?\d,一种用于 100-199:1\d\d,最后是 200-255:2(5[0-5]|[0-4]\d)

          这之前是对行首 .的测试,整个表达式由附加的{4}测试4次。

          这个完整的四字节表示测试从测试行首开始,然后进行否定前瞻以避免以.:^(?!\.) 开头的地址,并以行尾测试结束 (@987654331 @)。

          See some samples here at regex101.

          【讨论】:

            【解决方案15】:

            而不是

            {1-3}
            

            你应该放

            {1,3}
            

            【讨论】:

              【解决方案16】:
              \b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b
              

              匹配 0.0.0.0 到 999.999.999.999 如果您知道 seachdata 不包含无效的 IP 地址,请使用

              \b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b
              

              用于准确匹配 IP 号码 - 4 个号码中的每一个都存储在其自己的捕获组中,因此您可以稍后访问它们

              【讨论】:

                【解决方案17】:

                也许更好:

                function checkIP(ip) {
                    var x = ip.split("."), x1, x2, x3, x4;
                
                    if (x.length == 4) {
                        x1 = parseInt(x[0], 10);
                        x2 = parseInt(x[1], 10);
                        x3 = parseInt(x[2], 10);
                        x4 = parseInt(x[3], 10);
                
                        if (isNaN(x1) || isNaN(x2) || isNaN(x3) || isNaN(x4)) {
                            return false;
                        }
                
                        if ((x1 >= 0 && x1 <= 255) && (x2 >= 0 && x2 <= 255) && (x3 >= 0 && x3 <= 255) && (x4 >= 0 && x4 <= 255)) {
                            return true;
                        }
                    }
                    return false;
                }    
                

                【讨论】:

                  【解决方案18】:

                  这就是我所做的,它速度快而且效果很好:

                  function isIPv4Address(inputString) {
                      let regex = new RegExp(/^(([0-9]{1,3}\.){3}[0-9]{1,3})$/);
                      if(regex.test(inputString)){
                          let arInput = inputString.split(".")
                          for(let i of arInput){
                              if(i.length > 1 && i.charAt(0) === '0')
                                  return false;
                              else{
                                  if(parseInt(i) < 0 || parseInt(i) >=256)
                                     return false;
                              }
                          }
                      }
                      else
                          return false;
                      return true;
                  }
                  

                  解释:首先,使用正则表达式检查 IP 格式是否正确。虽然,正则表达式不会检查任何值范围。

                  我的意思是,如果您可以使用 Javascript 来管理正则表达式,为什么不使用它呢?因此,不要使用疯狂的正则表达式,而是仅使用正则表达式来检查格式是否正确,然后检查八位字节中的每个值是否在正确的值范围内(0 到 255)。希望这对其他人有帮助。和平。

                  【讨论】:

                    【解决方案19】:

                    上面的答案允许 IP 地址中的前导零,这是不正确的。 例如(“123.045.067.089”应该返回 false)。

                    这样做的正确方法。

                     function isValidIP(ipaddress) {  
                    if (/^(25[0-5]|2[0-4][0-9]|[1]?[1-9][1-9]?)\.(25[0-5]|2[0-4][0-9]|[1]?[1-9][1-9]?)\.(25[0-5]|2[0-4][0-9]|[1]?[1-9][1-9]?)\.(25[0-5]|2[0-4][0-9]|[1]?[1-9][1-9]?)$/.test(ipaddress)) {  
                      return (true)  
                    }   
                    return (false) } 
                    

                    此函数不允许零引导 IP 地址。

                    【讨论】:

                    • 这不适用于 ip: 1.1.1.10
                    【解决方案20】:

                    一直在寻找变化,似乎是一项重复的任务,那么使用 forEach 怎么样!

                    function checkIP(ip) {
                      //assume IP is valid to start, once false is found, always false
                      var test = true;
                    
                      //uses forEach method to test each block of IPv4 address
                      ip.split('.').forEach(validateIP4);
                    
                      if (!test) 
                        alert("Invalid IP4 format\n"+ip) 
                      else 
                        alert("IP4 format correct\n"+ip);
                    
                      function validateIP4(num, index, arr) {
                        //returns NaN if not an Int
                        item = parseInt(num, 10);
                        //test validates Int, 0-255 range and 4 bytes of address
                        // && test; at end required because this function called for each block
                        test = !isNaN(item) && !isNaN(num) && item >=0 && item < 256 && arr.length==4 && test;
                      }
                    }
                    

                    【讨论】:

                    • 如果字母字符出现在parseInt("2a00", 10) 返回2 而不是NaN 的部分中,则注释失败,因此200.200.2a00.200 的IP 最终被接受为有效,而不是。跨度>
                    • 感谢 Adam,修改代码以通过添加 isNaN(num) 来查看 parseInt 和原始 num
                    【解决方案21】:

                    除了没有正则表达式的解决方案:

                    const checkValidIpv4 = (entry) => {
                      const mainPipeline = [
                        block => !isNaN(parseInt(block, 10)),
                        block => parseInt(block,10) >= 0,
                        block => parseInt(block,10) <= 255,
                        block => String(block).length === 1
                          || String(block).length > 1
                          && String(block)[0] !== '0',
                      ];
                    
                      const blocks = entry.split(".");
                      if(blocks.length === 4
                        && !blocks.every(block => parseInt(block, 10) === 0)) {
                        return blocks.every(block =>
                          mainPipeline.every(ckeck => ckeck(block) )
                        );
                      }
                    
                      return false;
                    }
                    
                    console.log(checkValidIpv4('0.0.0.0')); //false
                    console.log(checkValidIpv4('0.0.0.1')); //true
                    console.log(checkValidIpv4('0.01.001.0')); //false
                    console.log(checkValidIpv4('8.0.8.0')); //true

                    【讨论】:

                      【解决方案22】:

                      在测试类型而不是有效性时不太严格。例如,当对列进行排序时,使用此检查来查看要使用的排序。

                      export const isIpAddress = (ipAddress) => 
                          /^((\d){1,3}\.){3}(\d){1,3}$/.test(ipAddress)
                      

                      检查有效性时,请使用此测试。更严格的测试检查 IP 8 位数是否在 0-255 范围内:

                      export const isValidIpAddress = (ipAddress) => 
                          /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipAddress)
                      

                      【讨论】:

                        猜你喜欢
                        • 2013-01-08
                        • 1970-01-01
                        • 2011-06-20
                        • 2017-03-15
                        • 2015-11-22
                        • 2016-02-07
                        相关资源
                        最近更新 更多