我正在尝试将一些字符串输入转换为使用MAC地址的正确格式。
所以我需要转换
00A0C914C829
到
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
我认为问题是我不明白小组如何正常工作......如果有人能指出我正确的方向,我真的很感激!
答案 0 :(得分:8)
以较小的单位来考虑它。实际上,您希望在每两个字符后插入:
(字符串末尾除外),而不是尝试捕获每个字符并将其强制为所需格式。
$s -replace '..(?!$)', '$&:'
此正则表达式一次匹配两个字符,并用相同的字符替换它们(替换字符串中的$&
表示匹配),后跟:
。除了在字符串的末尾,这是通过负向前瞻来防止字符串末尾的匹配。这是有效的,因为正则表达式引擎不会寻找向前延伸到先前匹配的匹配。因此,在匹配前两个字符后,下一个匹配只能在第一个之后发生。这隐含地为您提供了两个要替换的字符组。
如果你真的想要,你可以使用.
代替[0-9a-f]
,但我认为输入验证与输出格式不同。输出代码应该能够相信字符串确实只包含十六进制数字。
验证可以像
一样完成if ($s -notmatch '^[0-9a-f]{12}$') {
throw
}
通过这种方式检测格式错误的字符串实际上比通过检测替换是否无效而更容易。