2010-05-28 91 views
0

問題:.NET正則表達式字符串如何提取IPv6地址?.NET正則表達式:如何提取IPv6地址部分

我可以得到它提取一個簡單的IPv6地址,如「1050:0:0:0:5:600:300c:326b」,但不是冒號格式(「ff06 :: c3」);

我的問題是,它應該提取一個0之間的每個省略值:: 我該怎麼做?

下面我的代碼+說明。

通過省略前導零指定IPv6地址。
例如,IPv6地址1050:0000:0000:0000:0005:0600:300c:326b
可以寫爲1050:0:0:0:5:600:300c:326b。
雙冒號
使用雙冒號(:)代替一系列零指定IPv6地址。
例如,IPv6地址ff06:0:0:0:0:0:0:c3
可寫爲ff06 :: c3。
雙冒號只能在IP地址中使用一次。

 strInputString = "ff06::c3"; 
     strInputString = "1050:0000:0000:0000:0005:0600:300c:326b"; 

     string strPattern = "([A-Fa-f0-9]{1,4}:){7}([A-Fa-f0-9]{1,4})"; 
     //strPattern = @"\A(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\z"; 

     //strPattern = @"(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,6}\Z)|(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}\Z)|(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}\Z)|(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}\Z)|(\A([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}\Z)|(\A([0-9a-f]{1,4}:){1,6}(:[0-9a-f]{1,4}){1,1}\Z)|(\A(([0-9a-f]{1,4}:){1,7}|:):\Z)|(\A:(:[0-9a-f]{1,4}){1,7}\Z)|(\A((([0-9a-f]{1,4}:){6})(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|(\A(([0-9a-f]{1,4}:){5}[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|(\A([0-9a-f]{1,4}:){5}:[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,3}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,2}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,1}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A(([0-9a-f]{1,4}:){1,5}|:):(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A:(:[0-9a-f]{1,4}){1,5}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z) "; 
     //strPattern = @"/^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/"; 
     //strPattern = @"(:?[0-9a-fA-F]{1,4}:){7}([0-9a-fA-F]{1,4})\z"; 
     //strPattern = @"\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)\z"; 


     //strPattern = @"\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}:)*)(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\z"; 
     //strPattern = @"/^(?:(?:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9](?::|$)){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))$/i"; 

     System.Text.RegularExpressions.Regex reValidationRule = new System.Text.RegularExpressions.Regex("^" + strPattern + "$"); 


     if (reValidationRule.Match(strInputString).Success) // If matching pattern 
     { 
      System.Text.RegularExpressions.Match maResult = System.Text.RegularExpressions.Regex.Match(strInputString, strPattern); 
      // Console.WriteLine(maResult.Groups.Count) 

      string[] astrReturnValues = new string[4]; 


      System.Text.RegularExpressions.GroupCollection gc = maResult.Groups; 
      System.Text.RegularExpressions.CaptureCollection cc; 

      int counter; 
      //System.Web.Script.Serialization.JavaScriptSerializer jssJSONserializer = new System.Web.Script.Serialization.JavaScriptSerializer(); 
      //Console.WriteLine(jssJSONserializer.Serialize()); 
      // Loop through each group. 
      for (int i = 0; i < gc.Count; i++) 
      { 
       Console.WriteLine("Group: {0}", i); 
       cc = gc[i].Captures; 
       counter = cc.Count; 

       // Print number of captures in this group. 
       Console.WriteLine("Captures count = " + counter.ToString()); 

       // Loop through each capture in group. 
       for (int ii = 0; ii < counter; ii++) 
       { 
        Console.WriteLine("Capture: {0}", ii); 
        // Print capture and position. 
        Console.WriteLine(cc[ii] + " Starts at character " + 
         cc[ii].Index); 
       } 
      } 
+1

這個問題對你有幫助嗎? http://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses – Greg 2010-05-28 20:03:42

+0

不,這是驗證。我需要提取IP,以便我有: Number0 = 1050; Number1 = 0000; Number2 = 0000; Number3 = 0000; Number4 = 0005; Number5 = 0600; Number6 = 300c; Number7 = 326b; – 2010-05-29 10:23:03

+0

是否需要使用Regex?爲什麼不使用** byte [] ipBytes = IPAddress.Parse(strInputString).GetAddressBytes()**,然後將字節以您的首選格式放在一起? – 2012-11-06 17:36:25

回答

0

Regex.Replace()可能會幫助您的原因。你可以使用這樣的返回突變字符串「::」替換爲「0:」在一個字符串

var myStr = "test::me"; 
Console.WriteLine(Regex.Replace(myStr, @"::", ":0:")); 

我測試了這一點與LINQPad和它的工作對我蠻好。

+0

唯一的問題是你不知道多少「0:」被替換爲:: – 2010-05-29 10:20:22

+0

好吧,對不起,我以爲你遇到「::」並需要用「:0:」代替它。 – jlafay 2010-05-30 02:44:20

2
private static IEnumerable<string> Parse(string input) 
    { 
     const string partPattern = @"([A-Fa-f0-9]{1,4})"; 
     string longPattern = string.Format(@"{0} (?:\:{0})*", partPattern); //Group 1 -> 2 
     string compactPattern = string.Format(@"{0} (?:\:{0})* \:\: {0} (?:\:{0})*", partPattern, RegexOptions.IgnorePatternWhitespace); //Groups 3 ->6 
     string completePattern = string.Format(@"^{0}$ | ^{1}$", longPattern, compactPattern); 
     var match = Regex.Match(input, completePattern, RegexOptions.IgnorePatternWhitespace); 
     if (match.Success) 
     { 
      if (match.Groups[1].Success) 
      { 
       yield return match.Groups[1].Value.PadLeft(4, '0'); 
       for (int i = 0; i < match.Groups[2].Captures.Count; ++i) 
        yield return match.Groups[2].Captures[i].Value.PadLeft(4, '0'); 
      } 
      else 
      { 
       var count = 6 - match.Groups[4].Captures.Count - match.Groups[6].Captures.Count; 

       //First part 
       yield return match.Groups[3].Value.PadLeft(4, '0'); 
       for (int i = 0; i < match.Groups[4].Captures.Count; ++i) 
        yield return match.Groups[4].Captures[i].Value.PadLeft(4, '0'); 

       //:: block 
       for (int i = 0; i < count; ++i) 
        yield return "0000"; 

       //Second part 
       yield return match.Groups[5].Value.PadLeft(4, '0'); 
       for (int i = 0; i < match.Groups[6].Captures.Count; ++i) 
        yield return match.Groups[6].Captures[i].Value.PadLeft(4, '0'); 
      } 
     } 
     else 
      throw new Exception("No match"); 
    } 

這樣的事情應該工作。基本思想就是將包含::和其餘部分的地址分成兩種不同的模式。我使用了::不能在開始或結束的假設,所以如果不成立,你必須修改一些模式。