正则表达式 - 捕获Mac;执行匹配长度&删除中间匹配

时间:2014-05-01 16:24:54

标签: regex

我正在尝试编写一个正则表达式来捕获MAC,但我是通过手动人工输入以及以各种方式输入值来实现的。为此,我想仅限制没有分隔符的实际值(例如AABBCCDDEEFF),然后自己插入分隔符。

目前我的正则表达式是:

([0-9A-F]{2,12}(?:[:.,]?)(?: ?)){1,5}([0-9A-F]{2,4})(?:$| )

鉴于样本:

AABBCCDD11AA
AABB.CCDD.11AA
AB.BB.CC.DD.11.AA
AA.BB.CC.DD.11:AA   uselessText
UselessText AA.BB.CC.DD.11.AA   
MoreText:AA,BB:CC.DD.11.AA
AA. BB. CC. DD. 11. AA
AA, BB, CC, DD, 11, AA   uselessText
UselessText.:AA:BB:CC:DD: 11: AA
MoreText:00.AA.BB.CC.DD.11.AA
Text00.00.00.00.00.00
ABAB 
There's nothing to match on this line
01010101010 textUslessText

它确实接收MAC,但它也会选择无效值,包括“ABAB”和“01010101010”。此外,它仍然似乎在选择:。和/或,对于值分隔符,尽管有(?:$ |),它仍在接收终止空格。

所以我的问题实际上有三个部分:

  1. 如何强制执行X个字符的最终匹配?
  2. 为什么这仍然在(?:...)中选择字符?
  3. 为什么选择终止空格?
  4. 我从来没有对Regex感到满意,所以我可能会忽视它。

1 个答案:

答案 0 :(得分:1)

一个混乱的问题可能值得一个不优雅的,或至少是重复的,正规的表达。如果表达式([0-9A-F]{2})匹配MAC地址的一个字节且(?:[:., ]*)匹配允许的分隔符(包括空格),则MAC地址的完全展开的正则表达式为

([0-9A-F]{2})(?:[:., ]*)([0-9A-F]{2})(?:[:., ]*)([0-9A-F]{2})(?:[:., ]*)([0-9A-F]{2})(?:[:., ]*)([0-9A-F]{2})(?:[:., ]*)([0-9A-F]{2})

对于MAC地址的每个字节,这将产生包括分隔符以及捕获组1到6的匹配。格式化的MAC地址可以由捕获组和规范分隔符组成。

处理数据的C#示例代码如下:

List<string> vectors = new List<string>();
vectors.Add("AABBCCDD11AA");
vectors.Add("AABB.CCDD.11AA");
vectors.Add("AB.BB.CC.DD.11.AA");
vectors.Add("AA.BB.CC.DD.11:AA   uselessText");
vectors.Add("UselessText AA.BB.CC.DD.11.AA   ");
vectors.Add("MoreText:AA,BB:CC.DD.11.AA");
vectors.Add("AA. BB. CC. DD. 11. AA");
vectors.Add("AA, BB, CC, DD, 11, AA   uselessText");
vectors.Add("UselessText.:AA:BB:CC:DD: 11: AA");
vectors.Add("MoreText:00.AA.BB.CC.DD.11.AA");
vectors.Add("Text00.00.00.00.00.00");
vectors.Add("ABAB ");
vectors.Add("There's nothing to match on this line");
vectors.Add("01010101010 textUslessText");

snippetResult.Clear();

Regex regex = new Regex("([0-9A-F]{2})(?:[:., ]*)([0-9A-F]{2})(?:[:., ]*)([0-9A-F]{2})(?:[:., ]*)([0-9A-F]{2})(?:[:., ]*)([0-9A-F]{2})(?:[:., ]*)([0-9A-F]{2})");
foreach (string vector in vectors)
{
    Match match = regex.Match(vector);
    if (match.Success)
    {
        string mac
            = match.Groups[1].Value + ":"
            + match.Groups[2].Value + ":"
            + match.Groups[3].Value + ":"
            + match.Groups[4].Value + ":"
            + match.Groups[5].Value + ":"
            + match.Groups[6].Value;
        snippetResult.Text += "Match '";
        snippetResult.Text += match.Groups[0].Value;
        snippetResult.Text += "' ==> ";
        snippetResult.Text += mac;
        snippetResult.Text += Environment.NewLine;
    }
}

使用测试向量的输出是:

Match 'AABBCCDD11AA' ==> AA:BB:CC:DD:11:AA
Match 'AABB.CCDD.11AA' ==> AA:BB:CC:DD:11:AA
Match 'AB.BB.CC.DD.11.AA' ==> AB:BB:CC:DD:11:AA
Match 'AA.BB.CC.DD.11:AA' ==> AA:BB:CC:DD:11:AA
Match 'AA.BB.CC.DD.11.AA' ==> AA:BB:CC:DD:11:AA
Match 'AA,BB:CC.DD.11.AA' ==> AA:BB:CC:DD:11:AA
Match 'AA. BB. CC. DD. 11. AA' ==> AA:BB:CC:DD:11:AA
Match 'AA, BB, CC, DD, 11, AA' ==> AA:BB:CC:DD:11:AA
Match 'AA:BB:CC:DD: 11: AA' ==> AA:BB:CC:DD:11:AA
Match '00.AA.BB.CC.DD.11' ==> 00:AA:BB:CC:DD:11
Match '00.00.00.00.00.00' ==> 00:00:00:00:00:00