繁体   English   中英

Powershell Unicode 字符 - Em Dash

[英]Powershell Unicode Characters - Em Dash

我有一个 powershell 脚本,它使用以下命令从 API 中提取数据

Invoke-RestMethod -Method Post -Uri $WebServiceURL -Body $json -ContentType "Application/json" 

API 服务器端中的数据包含一个 Em Dash“-”。

当我使用 Postman 提取数据时,它会按原样显示 Em Dash,但是当我使用 Powershell 提取数据并打印 output 时,它会显示一些奇怪的字符,如下所示。

OUPath=ABCD.COM/Test/All Users/India/Test/TestâOU/Desktop Users

Em Dash 打印为“â”。

我尝试使用以下命令转换 Powershell 的 Output 编码,但没有运气。

[Console]::OutputEncoding = [Text.Encoding]::Utf8

当前 Powershell 版本详细信息。

PS Codes> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.19041.1
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.19041.1
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

默认 Output 编码如下:

PS Codes> [Console]::OutputEncoding


IsSingleByte      : True
BodyName          : IBM437
EncodingName      : OEM United States
HeaderName        : IBM437
WebName           : IBM437
WindowsCodePage   : 1252
IsBrowserDisplay  : False
IsBrowserSave     : False
IsMailNewsDisplay : False
IsMailNewsSave    : False
EncoderFallback   : System.Text.InternalEncoderBestFitFallback
DecoderFallback   : System.Text.InternalDecoderBestFitFallback
IsReadOnly        : True
CodePage          : 437

过去在这里回答了几个类似的问题(请参阅https://stackoverflow.com/a/58542493/3156906https://stackoverflow.com/a/66464671/315 )几件事的组合::

  • 服务器正在发送编码为 utf-8 的响应,但未Content-Encoding header 中添加字符集参数
  • 在没有字符集的情况下,PowerShell 遵循 HTTP 规范并解码为 ISO-8859-1,最终得到一个您正在逐字写入控制台的错位字符串
  • Postman 可能以某种方式检测到响应是 utf-8 即使没有字符集,并且正在解码响应 stream 很好

当然,如果charset参数那么这个答案的rest就是胡说八道!

无论如何,这里有一个简单的脚本来重现这个问题:

# server encodes response text using utf8
PS> $text = "`u{2014}"; # em dash
PS> $bytes = [System.Text.Encoding]::UTF8.GetBytes($text);
PS> write-host $bytes;
226 128 148

# client (Invoke-RestMethod) decodes bytes as ISO-8859-1
PS> $text = [System.Text.Encoding]::GetEncoding("ISO-8859-1").GetString($bytes);
PS> write-host $text;
â

不幸的是,在您的情况下,修改是不可逆的,因为正如@JosefZ在评论中指出的那样,当字节 stream 被解码时,一些编码字节被“阻塞”(即丢弃)。

我真正能建议的是:

  • 修复 API(如果您有权访问),使其发送“charset=utf-8”参数,或者,
  • 也许在下游处理发生之前硬编码一些特殊处理来修复已知的坏名
  • 或者,使用Invoke-RestMethod-OutFile参数将响应字节写入文件而不对其进行解码,然后将其作为 utf-8 编码文件读回。

顺便说一句,这是我以前用来检测什么编码/解码对导致给定重整的脚本——我每次都是从头开始编写的,所以这次我不妨把它贴在这里,这样我以后可以再次找到它: -)。


$original = "`u{2014}"; # em dash
$mangled  = "`u{00E2}"; # circumflex a

$encodings = [System.Text.Encoding]::GetEncodings() | sort-object -Property "Name";
foreach( $source in $encodings )
{
    foreach( $target in $encodings )
    {
        $bytes = [System.Text.Encoding]::GetEncoding($source.Name).GetBytes($original);
        $text  = [System.Text.Encoding]::GetEncoding($target.Name).GetString($bytes);
        if( $text -eq $mangled )
        {
            write-host "original string = '$original'";
            write-host "mangled string  = '$mangled'";
            write-host "    source encoding = '$($source.Name)'";
            write-host "    target encoding = '$($target.Name)'";
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM