子网掩码的正则表达式?

时间:2011-03-19 07:19:31

标签: c# asp.net

我正在使用正则表达式来检查子网掩码。我使用带有屏蔽值的ajax txtbox,但这不起作用,然后我切换到文本框并为其应用正则表达式。不幸的是,一个人也没有工作。

你能帮助我为子网掩码提供RE吗255.255.255.255

或者是最好的方法吗?

解决方案

我使用的是蒙面文本框,不知道如何放置验证表达式。

最后我发现了一个蒙版文本框的属性作为验证表达式,然后我把RE放在了,并将属性validate更改为true。

无需显式使用验证程序表达式。

谢谢

6 个答案:

答案 0 :(得分:11)

要使用正则表达式执行此操作,必须确保整个IPv4点分四边形表示仅包含前导数字的32位数字。仅仅确保四元组中的每个数字只有前导数字是不够的。例如,255.192.255.0不是有效的子掩码,即使四元组中的每个数字只有前导数字。基于@xanatos提供的解决方案,

var leadingOnes = new Regex("255|254|252|248|240|224|192|128|0+");

定义一个正则表达式,它将匹配任何8位(十进制)数字与仅前导数字。我使用“0+”来允许.000,有时用于四边形。显然,如果你想强迫零,请改为使用“0”。

然后,您必须构建一个正则表达式,该表达式匹配以下四种模式中的任何一种,我将其表示为伪正则表达式,以便于理解:

  • 255.255.255。 leadingOnes
  • 255.255。 leadingOnes *。0
  • 255 leadingOnes .0.0
  • leadingOnes .0.0.0

您可以将其写为单个字符串,也可以通过连接构建它。这是建立它:

var leadingOnes = "(255|254|252|248|240|224|192|128|0+);"
var allOnes = @"(255\.)"; 
var re = new Regex("^((" + allOnes + "{3}" + leadingOnes + ")|" +
                     "(" + allOnes + "{2}" + leadingOnes + @"\.0+)|" +
                     "(" + allOnes +         leadingOnes + @"(\.0+){2})|" +
                     "(" +                   leadingOnes + @"(\.0+){3}))$");

如果我们忽略换行符,这就是整个字符串。

var re = new Regex(@"^(((255\.){3}(255|254|252|248|240|224|192|128|0+))|((255\.){2}(255|254|252|248|240|224|192|128|0+)\.0)|((255\.)(255|254|252|248|240|224|192|128|0+)(\.0+){2})|((255|254|252|248|240|224|192|128|0+)(\.0+){3}))$");

按照@ Keith的建议,您可以从简单的正则表达式开始,例如

Regex("([0-9]{1,3}\.){3}[0-9]{1,3}"获取由点分隔的四个3位数字,然后编写一个函数,将四个部分提取并评估为32位整数,然后检查以确保它只有前导数。 有几种方法可以做到这一点,但所有这些方法都需要最多31次比较操作才能完成验证。

答案 1 :(得分:8)

如果您想接受任何IP地址作为子网掩码:

var num = @"(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})";
var rx = new Regex("^" + num + @"\." + num + @"\." + num + @"\." + num + "$");

我认为更容易在单独的变量中拆分单个数字组的“重复”匹配。

作为读者的练习,我将给出表达的另一种变体。这个将捕获同一组中的所有数字,但不同的捕获:

var rx = new Regex("^(?:" + num + @"(?:\.(?!$)|$)){4}$");

但这是错的,你应该使用这个

var num = @"(255|254|252|248|240|224|192|128|0+)";
var rx = new Regex("^" + num + @"\." + num + @"\." +num + @"\." +num + "$");

var rx = new Regex("^(?:" + num + @"(?:\.(?!$)|$)){4}$");

http://www.freesoft.org/CIE/Course/Subnet/6.htm

答案 2 :(得分:3)

来自http://pastebin.com/wTEKjKpP

var subnetRegex = /^((128|192|224|240|248|252|254)\.0\.0\.0)|(255\.(((0|128|192|224|240|248|252|254)\.0\.0)|(255\.(((0|128|192|224|240|248|252|254)\.0)|255\.(0|128|192|224|240|248|252|254)))))$/

当然这是针对javascript的,但这应该会有所帮助。

答案 3 :(得分:2)

我知道有关Regex表达式的问题,但对于其他任何感兴趣的人,这里有两个迭代解决方案。第二个函数比第一个函数快一点。

private bool IsValidSubnet(IPAddress ip) {
    byte[] validOctets = new byte[] { 255, 254, 252, 248, 240, 224, 192, 128, 0 };
    byte[] ipOctets = ip.GetAddressBytes();
    bool restAreZeros = false;
    for (int i = 0; i < 4; i++) {
        if (!validOctets.Contains(ipOctets[i]))
            return false;
        if (restAreZeros && ipOctets[i] != 0)
            return false;
        if (ipOctets[i] < 255)
            restAreZeros = true;
    }
    return true;
}

// checks if the address is all leading ones followed by only zeroes
private bool IsValidSubnet2(IPAddress ip) {
    byte[] ipOctets = ip.GetAddressBytes();
    bool restAreOnes = false;
    for (int i = 3; i >= 0; i--) {
        for (int j = 0; j < 8; j++) {
            bool bitValue = (ipOctets[i] >> j & 1) == 1;
            if (restAreOnes && !bitValue)
                return false;
            restAreOnes = bitValue;
        }
    }
    return true;
}

答案 4 :(得分:1)

您可以使用此正则表达式来验证子网

^(((255\.){3}(255|254|252|248|240|224|192|128+))|((255\.){2}(255|254|252|248|240|224|192|128|0+)\.0)|((255\.)(255|254|252|248|240|224|192|128|0+)(\.0+){2})|((255|254|252|248|240|224|192|128|0+)(\.0+){3}))$ 

答案 5 :(得分:0)

说明

派对有点晚了,但我们不能只对正确的八位字节进行正则表达式检查,因为:

  1. 子网必须以255.X.X.X
  2. 开头
  3. 子网不能如下所示:255.254.128.X - 一旦有0位,之后其他所有内容必须为0
  4. 正确的方法是从MSB走位,检查前0位。一旦发现前0位,检查它的位置。最大的合法子网是/ 8或255.0.0.0,这意味着在第一个零之前需要有8个1位。然后,确保第一个0之后的每个位都为零。总结如下:

    1. (可选择确认它甚至是有效的IP地址......)

    2. 从MSB开始,向下走,寻找第一个0

    3. 如果找到0(255.255.255.255仍然有效),请检查位置
    4. 检查所有剩余位是否为零
    5. 代码

          private bool IsValidSubnet(string subnet)
          {
              //A subnet is a valid ipv4 address, so start checking there
              if (!IsIPv4(subnet)) return false;
      
              // Get the 4 bytes
              byte[] subnetMaskBytes =
                          System.Net.IPAddress.Parse(subnet).GetAddressBytes();
      
              //Shift to get uint representation of the bits
              var UintSubnet = (uint)subnetMaskBytes[0] << 24;
              UintSubnet += (uint)subnetMaskBytes[1] << 16;
              UintSubnet += (uint)subnetMaskBytes[2] << 8;
              UintSubnet += (uint)subnetMaskBytes[3];
      
              int i = 31;
              while (i >= 0)
              {
                  UInt32 mask = (UInt32)(1 << i);
                  if ((UintSubnet & mask) == 0) break;
                  i--;
              }
      
              // It is not legal to have fewer than 8 bits of addressing
              if (i >= 24) return false;
      
              // Make sure that all remaining bits are 0
              while (i >= 0)
              {
                  UInt32 mask = (UInt32)(1 << i);
                  if ((UintSubnet & mask) != 0) return false;
                  i--;
              }
              return true;
          }