如何解决如何通过 PowerShell 将 JSON 中的环境变量扩展为有效的 JSON 表示法
当我尝试从包含环境变量的 JSON 中读取配置时,例如%USERPROFILE%\\source
一个明显的选择 [System.Environment]::ExpandEnvironmentvariables($jsonString)
将 JSON 字符串扩展为无效的 JSON 表示法,例如“C:\Users\JohnDoe”。 \U
不是有效的 JSON 符号。
问题是如何克服这个问题(使用一些干净的代码)。
解决方法
如果您在整个 $jsonString
上执行替换,那么,是的,$jsonString -replace '\\','\\'
将替换过多的反斜杠。
你最好这样做:
$match = ([regex] '(%([^%]+)%)').Match($jsonString)
while ($match.Success) {
$search = $match.Groups[1].Value
$replace = [environment]::GetEnvironmentVariable($match.Groups[2].Value) -replace '\\','\\'
$jsonString = $jsonString -replace $search,$replace
$match = $match.NextMatch()
}
这只会将匹配的 %SomeVar%
环境变量替换为它们扩展为双倍的所有可能的反斜杠。
使用一些伪造的 JSON 进行测试:
$jsonString = @"
{
"Name": "%USERNAME%","UserPath": "%USERPROFILE%\\source"
"WinDir": "%SystemRoot%"
"InetPath": "%SystemDrive%\\inetpub\\wwwroot",}
"@
$match = ([regex] '(%([^%]+)%)').Match($jsonString)
while ($match.Success) {
$search = $match.Groups[1].Value
$replace = [environment]::GetEnvironmentVariable($match.Groups[2].Value) -replace '\\','\\'
Write-Host $search
write-host $replace
$jsonString = $jsonString -replace $search,$replace
$match = $match.NextMatch()
}
$jsonString
输出:
{
"Name": "KUTlime","UserPath": "C:\\Users\\KUTlime\\source"
"WinDir": "C:\\WINDOWS"
"InetPath": "C:\\inetpub\\wwwroot",}
,
使用 Json
之类的字符串方法查看和插入 serialized 对象字符串(例如 XML
和 Replace
)通常是一种不好的做法。相反,最好将字符串反序列化为对象,进行更改,然后再次将其序列化为字符串。通过这种方式,您可以防止错误地替换具有特殊含义的反斜杠(例如双引号或 Unicode 字符的转义符)。
由于递归抓取复杂对象以扩展所有字符串可能很麻烦,因此我为此编写了一个小函数:
function Expand-String {
[CmdletBinding()] param(
[Parameter(ValueFromPipeLine = $True)]$Object
)
Process {
if ($Object -is [string]) { $Object = [System.Environment]::ExpandEnvironmentVariables($Object) }
elseif ($Object -is [Collections.IDictionary]) {
Foreach ($Key in @($Object.get_Keys())) { $Object[$Key] = Expand-String $Object[$Key] }
}
elseif ($Object -is [Collections.IEnumerable]) {
for ($i = 0; $i -lt $Object.Count; $i++) { $Object[$i] = Expand-String $Object[$i] }
}
else {
Foreach ($Name in ($Object.PSObject.Properties | Where-Object { $_.MemberType -eq 'NoteProperty' }).Name) {
$Object.$Name = Expand-String $Object.$Name
}
}
$Object
}
}
$Json = @'
{
"Environment Variables": {
"Name": "%USERNAME%","UserPath": "%USERPROFILE%\\source","WinDir": "%SystemRoot%","InetPath": "%SystemDrive%\\inetpub\\wwwroot"
},"Special Characters": {
"Quote": "Hello \"World\"","Unicode": ["\u1F60A","\u1F44D"]
}
}
'@
$Object = $Json | ConvertFrom-Json | Expand-String
$Object.'Environment Variables'
Name UserPath WinDir InetPath
---- -------- ------ --------
KUTlime C:\Users\KUTlime\source C:\WINDOWS C:\inetpub\wwwroot
$Json = $Object | ConvertTo-Json -Depth 9
$Json
{
"Environment Variables": {
"Name": "KUTlime","UserPath": "C:\\Users\\KUTlime\\source","WinDir": "C:\\WINDOWS","InetPath": "C:\\inetpub\\wwwroot"
},"Special Characters": {
"Quote": "Hello \"World\"","Unicode": [
"ὠA","ὄD"
]
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。