我正在 PowerShell 中编写一个语言解释器(该语言是 PILOT,对于那些可能感兴趣的人),并且我已经达到了实现变量替换的地步。变量名由以下任一组成:$
or a #
,后跟该集中最多十个字符[A-Za-z0-9]
。但是,如果变量名带有前缀\
, 它应该not被替换。据我所知,我想要匹配的模式是[^\\][\$#]\w{,10}
,但我不清楚如何将匹配结果存储在 PowerShell 变量中,以便我可以在表中查找变量名称以将其替换为其值。
例如,如果 powershell 变量$expr
包含字符串\#Foo has the value #Foo
, and $vartable["#Foo"]
包含值5
,我需要捕获#Foo
- 仅第二个 - 在 $varname 中,然后替换捕获的内容#Foo
与 $vartable[$varname] -$expr -replace "[^\\][\$#]\w{,10}",$vartable[$varname]
应该产生\#Foo has the value 5
.
我是否正确计算了模式?如何捕获匹配?
(我应该指出,我正在使用 PowerShell 5.1 进行开发,但希望它能够在该版本或更高版本中运行,包括非 Windows 操作系统上的 PSCore。)
The [^\\]
模式是usually这不是检查字符是否被转义的有效方法,因为反斜杠也可能被转义以表示文字反斜杠字符。例如,\\#Foo
有一个未转义的变量,必须根据原始要求进行匹配。有效的方法是使用(?<=(?<!\\)(?:\\{2})*)
.NET 兼容的lookbehind,匹配紧接在前面没有反斜杠的任何数量的偶数反斜杠的位置。
接下来,您不能在字符串替换模式内使用代码。您可以在内部使用回调[regex]::Replace
或者 - 从 PowerShell Core v6.1 开始 - 您可以使用脚本块作为替换参数-replace
:
[regex]::Replace($s,'(?<=(?<!\\)(?:\\{2})*)[$#]\w{1,10}\b', {param($match) $vartable[$match.Value] })
或(PowerShell Core v6.1+):
$s -replace '(?<=(?<!\\)(?:\\{2})*)[$#]\w{1,10}\b', { $vartable[$_.Value] }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)