如何将 RegEx 令牌传递给 RegEx 替换中的 PowerShell 子表达式?
How do I pass a RegEx token to a PowerShell subexpression in a RegEx substitution?
我有以下代码:-
'\u0026' -replace '(\u)(\d{4})', '$$([char]0x)'
这显然会导致:-
$([char]0x0026)
如果我将 RegEx 替换为可扩展字符串:-
'\u0026' -replace '(\u)(\d{4})', "$([char]0x`)"
那么我会得到:-
Unexpected token '0x`$' in expression or statement.
如果我将事情简化为:-
'\u0026' -replace '(\u)(\d{4})', "0x`"
然后我可以得到:-
0x0026
但是,我想要的是将“0x0026”转换为一个字符,以便将“\u0026”替换为“&”。但是,似乎不可能以这种方式将 RegEx 替换标记传递给 PowerShell 子表达式。如果您将两种语言分开:-
'\u0026' -replace '(\u)(\d{4})', "$([char]0x0026) 0x`"
则结果如下:-
& 0x0026
这很棒,因为它表明 PowerShell 子表达式在 RegEx 替换中确实有效,如转换后的 & 符号所示。
我是正则表达式的新手。我已经达到极限了吗?
使用脚本块替换(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', '(\u)(\d{4})', {param($m) "0x$($m.Groups[2].Value)"})
0x0026
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]) }
+
显然,您想要 unescape 和 escaped 正则表达式。您可以使用 .net [regex]
unescape
方法执行此操作:
[Regex]::Unescape('Jack\u0026Jill')
产量:
Jack&Jill
我有以下代码:-
'\u0026' -replace '(\u)(\d{4})', '$$([char]0x)'
这显然会导致:-
$([char]0x0026)
如果我将 RegEx 替换为可扩展字符串:-
'\u0026' -replace '(\u)(\d{4})', "$([char]0x`)"
那么我会得到:-
Unexpected token '0x`$' in expression or statement.
如果我将事情简化为:-
'\u0026' -replace '(\u)(\d{4})', "0x`"
然后我可以得到:-
0x0026
但是,我想要的是将“0x0026”转换为一个字符,以便将“\u0026”替换为“&”。但是,似乎不可能以这种方式将 RegEx 替换标记传递给 PowerShell 子表达式。如果您将两种语言分开:-
'\u0026' -replace '(\u)(\d{4})', "$([char]0x0026) 0x`"
则结果如下:-
& 0x0026
这很棒,因为它表明 PowerShell 子表达式在 RegEx 替换中确实有效,如转换后的 & 符号所示。
我是正则表达式的新手。我已经达到极限了吗?
使用脚本块替换(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', '(\u)(\d{4})', {param($m) "0x$($m.Groups[2].Value)"})
0x0026
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]) }
+
显然,您想要 unescape 和 escaped 正则表达式。您可以使用 .net [regex]
unescape
方法执行此操作:
[Regex]::Unescape('Jack\u0026Jill')
产量:
Jack&Jill