如何在 RegEx 替换中将 RegEx 令牌传递给 PowerShell 子表达式?
Posted
技术标签:
【中文标题】如何在 RegEx 替换中将 RegEx 令牌传递给 PowerShell 子表达式?【英文标题】:How do I pass a RegEx token to a PowerShell subexpression in a RegEx substitution? 【发布时间】:2021-07-30 09:28:19 【问题描述】:我有以下代码:-
'\u0026' -replace '(\u)(\d4)', '$$([char]0x$2)'
这显然会导致:-
$([char]0x0026)
如果我将 RegEx 替换为可扩展字符串:-
'\u0026' -replace '(\\u)(\d4)', "$([char]0x`$2)"
然后我会得到:-
表达式或语句中出现意外的标记“0x`$”。
如果我将事情简化为:-
'\u0026' -replace '(\\u)(\d4)', "0x`$2"
那么我可以得到:-
0x0026
但是,我想要将“0x0026”转换为字符,以便将“\u0026”替换为“&”。但是,以这种方式将 RegEx 替换标记传递给 PowerShell 子表达式似乎是不可能的。如果您将两种语言分开:-
'\u0026' -replace '(\\u)(\d4)', "$([char]0x0026) 0x`$2"
然后会出现以下结果:-
&0x0026
这很好,因为它表明 PowerShell 子表达式在正则表达式替换中确实有效,正如转换后的 & 符号所示。
我是 RegEx 的新手。我已经达到我的极限了吗?
【问题讨论】:
也许你应该解释你想要做什么,而不是你是怎么做的。 (见:What the XY problem?) 啊,所以你想修改文件中的 html 源代码?您能否在问题中包含此类文件的示例? 我完全同意@Tomalak,提出的问题是XY problem。要摆脱这个XY
循环,问问自己WHY???(问题中的每个定义)?如:为什么要“& 0x0026
”? (并将该信息添加到问题中)。我猜你只是想这样做:[Regex]::Unescape('Jack\u0026Jill')
。但即使这样也是一个有问题的答案,因为通常不需要unescape 一个正则表达式......
我们仍然没有解决您的实际问题,而只是解决了它的症状。没有理由为什么\u0026
甚至会出现在 HTML 中,除非在生成 HTML 时出现问题(那么这应该被修复),或者它在 JSON 字符串中(然后应该使用 JSON 解析器)。通过正则表达式替换这些转义序列是可能的,但它根本不像您真正需要的东西。
@Tomalak - 你是对的,未来也不会有任何修复它的计划,但这不在我的掌控之中。 Intranet 页面是 Sharepoint 页面,我在某处读到某些字符会以这种方式转义。很抱歉没有正确解释背景场景,但我非常感谢大家对此的投入。作为我自己在这个网站上的第一个 OP,我会学习我的错误,下次会更清楚。
【参考方案1】:
显然,您想要 unescape 一个 转义 正则表达式。您可以使用 .net [regex]
unescape
方法来做到这一点:
[Regex]::Unescape('Jack\u0026Jill')
产量:
Jack&Jill
【讨论】:
【参考方案2】:在 powershell 7 中有一种方法,其中 -replace 的第二个参数可以是一个脚本块。使用$_
获得第二个匹配组需要更多工作:
'\u0026' -replace '(\\u)(\d4)', $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)(\d4)', [char][int]('0x' + $_.groups[2])
&
请注意,\d
不会匹配所有十六进制数字。 ([[:xdigit:]]
不起作用。)
'\u002b' -replace '(\\u)([0-9a-f]4)', [char][int]('0x' + $_.groups[2])
+
【讨论】:
【参考方案3】:使用脚本块替换(6.2 及更高版本):
'\u0026' -replace '(\\u)(\d4)', "0x$($_.Groups[2].Value)"
在早期版本的 PowerShell 中,您可以通过调用 [Regex]::Replace()
来执行相同操作:
[regex]::Replace('\u0026', '(\\u)(\d4)', param($m) "0x$($m.Groups[2].Value)")
在这两种情况下,该块将充当每个匹配项的回调,允许您构造替换字符串 after 访问匹配的子字符串,但 before 替换发生:
PS ~> [regex]::Replace('\u0026', '(\\u)(\d4)', param($m) "0x$($m.Groups[2].Value)")
0x0026
【讨论】:
以上是关于如何在 RegEx 替换中将 RegEx 令牌传递给 PowerShell 子表达式?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 C# 中使用 Regex 将 [number] 替换为 number - 1?
在sublime text和vs code中使用Regex进行替换的方式