正则表达式匹配MAC地址(不同的分隔符,格式等)

时间:2015-03-06 22:15:22

标签: python regex network-programming mac-address regex-lookarounds

我试图找到一个兼容Python的Regex表达式,它最适合匹配MAC地址,但排除可能被误认为的东西(例如,SSH密钥)。另外,我想匹配不同的分隔符(例如 - ,或 ),不同的格式(例如,* nix,Windows,Cisco)和字符串(例如,没有分隔符)。

另外,我试图找到符合我要求的最短答案(,正则表达式)。


以下是一些有助于缩小可能性的示例数据:

必须匹配以下内容中的MAC地址(即不包括额外的特殊字符):

(13:14:5f:cD:42:5f)
#13-14-5f-cD-42-5f
13.14.5f.cD.42.5f/
1314:5fcD:425f#
"1314.5fcD.425f"
1314-5fcD-425f
13145fcD425f
#13145fcD425f:

不得与以下任何内容匹配:

56:32:13:14:5f:cD:42:5f:65
56-32-13-14-5f-cD-42-5f-65
56.32.13.14.5f.cD.42.5f.65
13:14:5f:cD:42:5f:
:13:14:5f:cD:42:5f
111113:14:5f:cD:42:5ffff
ff13:14:5f:cD:42:5f
1314-5fcD.425f
1314-5f.cD:425f
13:14.5f:cD:42-5f
45fcD4
fcD4
13145fcD425f13145fcD425f
aa13145fcD425f13145fcD425fff

1 个答案:

答案 0 :(得分:1)

这是我最终想出来的。我将尝试在标题为注释的部分中概述下面的详细信息。我故意留下三个冗余/不必要的非捕获组,但这有助于划分三个路径中每个路径的代码。

我非常感谢您的反馈。感谢。


\b(?:(?<![-:\.])(?:(?:[0-9A-Fa-f]{2}(?=([-:\.]))(?:\1[0-9A-Fa-f]{2}){5})|(?:[0-9A-Fa-f]{4}(?=([-:\.]))(?:\2[0-9A-Fa-f]{4}){2}))(?![-:\.])|(?:[0-9A-Fa-f]{12}))\b

Regular expression visualization

Debuggex Demo

备注:

  • 我将正则表达式写入严格 - ly 匹配分隔符,这意味着MAC地址中的分隔符必须在整个匹配过程中通过反向引用相同(例如,hh:hh:hh:hh:hh:hh,not hh-hh:hh.hh:hh-hh&amp; not hh:hh:hh:hh:hh-hh)
  • 分隔符分组在方括号[]中,表示内部的任何项目可能匹配
  • 其中使用的三个主要分隔符分别是[-:\.]短划线/连字符,冒号和句点/点。
  • 我逃脱了\.(点),因为它有一个含糊不清的含义(例如.可能意味着任何字符,这不是我想要的东西。)
  • 除了我的两个群组外,所有群组都是非捕获群组,因此它们以(?:开头,以匹配的)结束。
  • |(管道)代表OR,导致分支
  • \b(字边界)阻止在字符串中间找到匹配项(例如,第7-8行,第19-20行)
  • 路径:1
    • (?<![-:\.])&amp; (?![-:\.])(负向后观和负向前瞻)会阻止在SSH密钥中找到的匹配(虽然这里只需要冒号,但不能说我已经看到用于密钥的其他两个分隔符)
    • 路径:1.1 * nix / Windows匹配格式:分隔的十六进制字符对(例如,hh:hh:hh:hh:hh:hh)
      • [0-9A-Fa-f]{2} hex char重复两次
      • (?=([-:\.])) lookahead&amp;捕获(内部parens)分隔符(捕获组\1
      • \1匹配存储在捕获组\1中的第一个分隔符,(?:\1[0-9A-Fa-f]{2}){5}重复分隔符&amp;十六进制对模式五次
    • 路径:1.2 思科匹配格式:四边形字符分隔(例如,hhhh.hhhh.hhhh)
      • [0-9A-Fa-f]{4} hex char重复四次
      • (?=([-:\.])) lookahead&amp;捕获(内部parens)分隔符(捕获组\2
      • \2匹配存储在捕获组\2中的第二个分隔符,(?:\2[0-9A-Fa-f]{4}){2}重复分隔符&amp;四个十六进制字符模式两次
  • 路径:2 字符串匹配格式:所有12个十六进制字符,非分隔(例如,hhhhhhhhhhhhh)
    • [0-9A-Fa-f]{12}十六进制重复十二次
    • 不需要在字符串之前或之后没有分隔符,因为没有在内部使用分隔符,并且能够匹配示例行9&amp; 16(但仍然遵循边界一词)

为了满足尽可能最短的答案,根据OP的要求,从上面的答案我已经删除了非捕获组(,使它们成为所有捕获组)和额外的为清晰起见,我得到 140 字符:

\b((?<![-:\.])([0-9A-Fa-f]{2}(?=([-:\.]))(\3[0-9A-Fa-f]{2}){5}|[0-9A-Fa-f]{4}(?=([-:\.]))(\5[0-9A-Fa-f]{4}){2})(?![-:\.])|[0-9A-Fa-f]{12})\b

这是我用于验证的样本:

56:32:13:14:5f:cD:42:5f:65
(13:14:5f:cD:42:5f)
#13-14-5f-cD-42-5f
56-32-13-14-5f-cD-42-5f-65
13.14.5f.cD.42.5f/
56.32.13.14.5f.cD.42.5f.65
111113:14:5f:cD:42:5ffff
ff13:14:5f:cD:42:5f
1314:5fcD:425f#
1314.5fcD.425f)
1314-5fcD-425f
1314-5fcD.425f
1314-5f.cD:425f
13:14.5f:cD:42-5f
13145fcD425f
#13145fcD425f:
45fcD4
fcD4
13145fcD425f13145fcD425f
aa13145fcD425f13145fcD425fff