问题描述
'\u0026' -replace '(\u)(\d{4})','$$([char]0x$2)'
这显然会导致:-
$([char]0x0026)
如果我将 RegEx 替换为一个可扩展的字符串:-
'\u0026' -replace '(\\u)(\d{4})',"$([char]0x`${2})"
然后我会得到:-
表达式或语句中出现意外标记“0x`$”。
如果我将事情简化为:-
'\u0026' -replace '(\\u)(\d{4})',"0x`${2}"
然后我可以得到:-
0x0026
但是,我想要的是将 '0x0026' 转换为字符,以便将 '\u0026' 替换为 '&'。但是,以这种方式将 RegEx 替换标记传递给 PowerShell 子表达式似乎是不可能的。如果您使用以下两种语言分开:-
'\u0026' -replace '(\\u)(\d{4})',"$([char]0x0026) 0x`${2}"
那么结果如下:-
& 0x0026
这很棒,因为它表明 PowerShell 子表达式确实在 RegEx 替换中起作用,如转换后的&符号所示。
我是 RegEx 的新手。我已经达到我的极限了吗?
解决方法
显然,您想要取消转义一个转义正则表达式。您可以使用 .net [regex]
unescape
方法执行此操作:
[Regex]::Unescape('Jack\u0026Jill')
产量:
Jack&Jill
,
在 powershell 7 中有一种方法,其中 -replace 的第二个参数可以是一个脚本块。使用 $_
获取第二个匹配组需要做更多的工作:
'\u0026' -replace '(\\u)(\d{4})',{ $b = $_ }
$b.groups
Groups : {0,1,2}
Success : True
Name : 0
Captures : {0}
Index : 0
Length : 6
Value : \u0026
Success : True
Name : 1
Captures : {1}
Index : 0
Length : 2
Value : \u
Success : True
Name : 2
Captures : {2}
Index : 2
Length : 4
Value : 0026
'\u0026' -replace '(\\u)(\d{4})',{ [char][int]('0x' + $_.groups[2]) }
&
请注意,\d
不会匹配所有十六进制数字。 ([[:xdigit:]]
不起作用。)
'\u002b' -replace '(\\u)([0-9a-f]{4})',{ [char][int]('0x' + $_.groups[2]) }
+
,
使用脚本块替换(6.2 及更高版本):
'\u0026' -replace '(\\u)(\d{4})',{"0x$($_.Groups[2].Value)"}
在早期版本的 PowerShell 中,您可以通过调用 [Regex]::Replace()
来执行相同的操作:
[regex]::Replace('\u0026','(\\u)(\d{4})',{param($m) "0x$($m.Groups[2].Value)"})
在这两种情况下,该块都将作为每个匹配项的回调,允许您在之后构建替换字符串以访问匹配的子字符串,但之前 替换发生:
PS ~> [regex]::Replace('\u0026',{param($m) "0x$($m.Groups[2].Value)"})
0x0026