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

如何通过 PowerShell 将 JSON 中的环境变量扩展为有效的 JSON 表示法

如何解决如何通过 PowerShell 将 JSON 中的环境变量扩展为有效的 JSON 表示法

这个问题与我的另一个question和这个issue有关。

当我尝试从包含环境变量的 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 对象字符串(例如 XMLReplace)通常是一种不好的做法。相反,最好将字符串反序列化为对象,进行更改,然后再次将其序列化为字符串。通过这种方式,您可以防止错误地替换具有特殊含义的反斜杠(例如双引号或 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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?