带有特殊字符的ConvertTo-Json带有或不带有Unscape-结果错误

Rez*_*aei 5 powershell

我有一个文件,其中包含一些属性,其中某些属性的值包含转义符,例如一些Urls和Regex模式。

在读取内容并转换回json时,无论是否进行转义,内容都不正确。如果我使用转义转义转换回json,则某些正则表达式会中断;如果我使用转义转义转换,则url和某些正则表达式会中断。

我该如何解决这个问题?

最少完整的可验证示例

以下是一些简单的代码块,可让您简单地重现该问题:

内容

$fileContent = 
@"
{
    "something":  "http://domain/?x=1&y=2",
    "pattern":  "^(?!(\\`|\\~|\\!|\\@|\\#|\\$|\\||\\\\|\\'|\\\")).*"
}
"@
Run Code Online (Sandbox Code Playgroud)

随着逃脱

如果我阅读了内容,然后使用以下命令将内容转换回json:

$fileContent | ConvertFrom-Json | ConvertTo-Json | %{[regex]::Unescape($_)}
Run Code Online (Sandbox Code Playgroud)

输出(错误)将是:

{
    "something":  "http://domain/?x=1&y=2",
    "pattern":  "^(?!(\|\~|\!|\@|\#|\$|\||\\|\'|\")).*"
}
Run Code Online (Sandbox Code Playgroud)

没有逃脱

如果我阅读了内容,然后使用以下命令将内容转换回json:

$fileContent | ConvertFrom-Json | ConvertTo-Json 
Run Code Online (Sandbox Code Playgroud)

输出(错误)将是:

{
    "something":  "http://domain/?x=1\u0026y=2",
    "pattern":  "^(?!(\\|\\~|\\!|\\@|\\#|\\$|\\||\\\\|\\\u0027|\\\")).*"
}
Run Code Online (Sandbox Code Playgroud)

Rez*_*aei 11

我决定使用Unscape,而是将unicode \uxxxx字符替换为其字符串值,现在可以正常使用:

$fileContent = 
@"
{
    "something":  "http://domain/?x=1&y=2",
    "pattern":  "^(?!(\\`|\\~|\\!|\\@|\\#|\\$|\\||\\\\|\\'|\\\")).*"
}
"@

$fileContent | ConvertFrom-Json | ConvertTo-Json | %{
    [Regex]::Replace($_, 
        "\\u(?<Value>[a-zA-Z0-9]{4})", {
            param($m) ([char]([int]::Parse($m.Groups['Value'].Value,
                [System.Globalization.NumberStyles]::HexNumber))).ToString() } )}
Run Code Online (Sandbox Code Playgroud)

产生预期的输出:

{
    "something":  "http://domain/?x=1&y=\\2",
    "pattern":  "^(?!(\\|\\~|\\!|\\@|\\#|\\$|\\||\\\\|\\'|\\\")).*"
}
Run Code Online (Sandbox Code Playgroud)

  • 这对于解决编辑ARM(Azure资源管理器)模板的问题最有帮助。 (3认同)
  • 这正是我想要的,以使Powershell的JSON输出可与我的Python解析器互操作...似乎微软真的使Powershell几乎无法使用JSON(默认情况下ConvertTo-JSON用BOM写入UTF-8文件,在REST世界中也无法使用)...总之,非常感谢:) (2认同)
  • @Ilyan 你的建议不能处理 \u 是字符串开头的情况。似乎这个正则表达式可以处理它 (?&lt;![\\\])\\u(?&lt;Value&gt;[a-zA-Z0-9]{4})。添加 **(?&lt;![\\\])** (2认同)