微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 RegEx 替换中将 RegEx 令牌传递给 PowerShell 子表达式?

如何解决如何在 RegEx 替换中将 RegEx 令牌传递给 PowerShell 子表达式?

我有以下代码:-

'\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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。