问题:.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);
}
}
答案 0 :(得分: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");
}
这样的事情应该有效。基本思路是将包含::和其余地址的大小写分成两种不同的模式。我使用了这样的假设:::永远不会在开头或结尾,所以如果不能保持你将不得不修改模式。
答案 1 :(得分:0)
Regex.Replace()可能有助于您的事业。您可以像这样使用它来返回一个变换的字符串,其中“::”替换为字符串中的“:0:”
var myStr = "test::me";
Console.WriteLine( Regex.Replace(myStr, @"::", ":0:") );
我用LINQPad对它进行了测试,它对我来说效果很好。