C# 子网掩码的正则表达式?

C# 子网掩码的正则表达式?,c#,asp.net,C#,Asp.net,我正在使用正则表达式检查子网掩码。我使用带有屏蔽值的ajax txtbox,但这不起作用,然后我切换到一个文本框并为此应用正则表达式。不幸的是,这一点也不起作用 你能帮我给255.255.255.255子网掩码一个RE吗 或者有什么最好的方法 解决方案: 我使用的是屏蔽文本框,不知道如何放置验证表达式 最后,我找到了一个蒙面文本框的属性作为验证表达式,在那里我放置了RE并将属性validate更改为true 无需显式使用验证器表达式 如果您想接受任何IP地址作为子网掩码,请感谢: var num

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

你能帮我给255.255.255.255子网掩码一个RE吗

或者有什么最好的方法

解决方案

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

最后,我找到了一个蒙面文本框的属性作为验证表达式,在那里我放置了RE并将属性validate更改为true

无需显式使用验证器表达式


如果您想接受任何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 + "$");


要使用正则表达式执行此操作,您必须确保整个IPv4虚线四元组仅代表一个带前导的32位数字。仅确保四元组中的每个数字只有前导数字是不够的。例如,255.192.255.0不是有效的子掩码,即使四元组中的每个数字只有前导数字。以@xanatos提供的解决方案为基础

var leadingOnes=新正则表达式(“255 | 254 | 252 | 248 | 240 | 224 | 192 | 128 | 0+”

定义一个正则表达式,该正则表达式将仅与前导数字匹配任何8位(十进制)数字。我使用“0+”来允许.000,这有时在四元组中使用。显然,如果你想强制一个零,用“0”代替

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

  • 255.255.255.引线元件
  • 255.255.引线元件*.0
  • 255.铅酮。0.0
  • 铅酮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 R R R=新监管局((((255)代码>var R R R R R R=新监管监管局(((((255)码)代码>代码>var R R R R R R R R R再=新监管监管局(((((((255)码)重重重数)新监管局(((((((255)码码)再再)新监管监管监管局((((())上述上述上述上述上述上述))再再再)新监管监管监管局(((((((((((((((((((((((((255)))))))上述上述上述))))再)再)再)再)再)再)再)再)再)新监管监管监管监管监管监管监管监管局)新监管局)新监管监管局)新监管局)新监管监管局)新监管局)新监管监管监管局)新监管监管局)新监管局((((((((((.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个比较操作才能完成验证。

我知道这个问题当被问及正则表达式时,对于其他感兴趣的人,这里有两个迭代解决方案。第二个函数比第一个函数快一点

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;
}
private bool IsValidSubnet(ip地址ip){
byte[]validocets=新字节[]{255、254、252、248、240、224、192、128、0};
byte[]ipOctets=ip.GetAddressBytes();
bool restAreZeros=false;
对于(int i=0;i<4;i++){
如果(!validocets.Contains(ipOctets[i]))
返回false;
如果(重新设置零和ipOctets[i]!=0)
返回false;
if(ipOctets[i]<255)
restAreZeros=真;
}
返回true;
}
//检查地址是否都是前导1,后面只有0
专用布尔IsValidSubnet2(ip地址ip){
byte[]ipOctets=ip.GetAddressBytes();
bool restreones=假;
对于(int i=3;i>=0;i--){
对于(int j=0;j<8;j++){
布尔比特值=(ipOctets[i]>>j&1)==1;
if(重新定义&&!位值)
返回false;
restAreOnes=位值;
}
}
返回true;
}
来自

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

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

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

  • (可选地验证它是否是有效的IP地址…)

  • 从MSB开始,向下遍历位以查找前0

  • 如果找到0(255.255.255.255仍然有效),请检查位置
  • 检查所有剩余位是否为零
  • 代码
    private bool IsValidSubnet(字符串子网)
    {
    //子网是有效的ipv4地址,因此请开始检查该子网
    如果(!IsIPv4(子网))返回false;
    //获取4个字节
    字节[]子网掩码字节=
    System.Net.IPAddress.Parse(子网).GetAddressBytes();
    //移位以获取位的uint表示形式
    
    var UintSubnet=(uint)subnetMaskBytes[0]您可以使用此正则表达式验证子网

    ^(((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}))$ 
    

    我认为只编写一个函数将掩码转换为整数并检查左侧(msb)的连续位会更快更容易。通过读取该函数,似乎“有效”数字的数量非常少。您可以轻松检查int是否只包含一些位算术和单个com的前导数
    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)))))$/
    
        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;
        }
    
    ^(((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}))$