将普通字符串转换为MAC地址格式

3
我正在尝试将一些字符串输入转换为与MAC地址配合使用的正确格式。因此,我需要进行转换。
00A0C914C829

to

00:A0:C9:14:C8:29

我有这个 PowerShell 脚本来实现这个。
$string = "00A0C914C829"
$out = $string -replace "([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])", '$1$2:$3$4:$5$6:$7$8:$9$10:$11$12'
$out

这句话的意思是:"输出结果为:"
00:A0:C9:14:C8:29

但是这个正则表达式看起来太长了。

有没有办法使它更简洁?


  • 我认为我需要使用()将每个部分分组成变量,这就是为什么它这么长的原因。我还尝试使用^([0-9A-Fa-f]){12}$进行匹配,但是这给出了输出9$2:$3$4:$5$6:$7$8:$9$10:$11$12(12个由1个字符组成的组)
  • 我还尝试了类似的正则表达式^(([0-9A-Fa-f]){2}){6}$(6组由2个字符组成的组),然后是替换:$1:$2:$3:$4:$5:$6,但这给出了输出29:9:$3:$4:$5:$6

我认为问题在于我不理解如何正确地使用组...如果有人能指点我一下就好了!


尝试使用正则表达式[\da-fA-F]{2}(?=([\da-fA-F]{2})+$)进行匹配,并将其替换为$&: - Pranav C Balan
[\da-fA-F]{2}(?=(?:[\da-fA-F]{2})+$) - Pranav C Balan
你需要实际(预)验证你匹配的字符串,还是它总是与上面的格式相同?如果是的话,Joey的解决方案适用于你。 - Wiktor Stribiżew
2个回答

10

从较小的单位考虑。实际上,您想要在每两个字符之后(除了字符串末尾)插入 :,而不是试图捕获每个单独的字符并将其强制转换为所需的格式。

$s -replace '..(?!$)', '$&:'

这个正则表达式每次匹配两个字符,并将它们替换为相同的字符(替换字符串中的$&代表匹配结果),后跟:。除了在字符串末尾,通过负向先行断言来防止在字符串末尾匹配。这是因为正则引擎不会查找向后延伸到以前匹配的匹配项。因此,在匹配了前两个字符之后,下一个匹配只能发生在那个第一个匹配之后。隐含给出了需要替换成两个字符的组。

如果你真的想要的话,你也可以使用[0-9a-f]而不是.,但我认为这里输入验证是一个不同的问题,与输出格式化无关。输出代码应该能够信任字符串确实只包含十六进制数字。

验证可以简单地完成

if ($s -notmatch '^[0-9a-f]{12}$') {
  throw
}

这种方法实际上比检测替换是否无效更容易检测到格式不正确的字符串。


0
补充一下Joey的回答。.NET有一个内置验证的PhysicalAddress类。解析方法接受多种格式。

https://learn.microsoft.com/en-us/dotnet/api/system.net.networkinformation.physicaladdress.parse?view=net-5.0#System_Net_NetworkInformation_PhysicalAddress_Parse_System_String_

001122334455

00-11-22-33-44-55

0011.2233.4455(仅适用于.NET 5及更高版本)

00:11:22:33:44:55(仅适用于.NET 5及更高版本)

F0-E1-D2-C3-B4-A5

f0-e1-d2-c3-b4-a5(仅适用于.NET 5及更高版本)

您需要安装PS7才能解析其中一些格式。我需要它来解析Cisco IOS格式。


虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。仅有链接的答案如果链接页面发生更改可能会变得无效。 - Tyler2P

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接