【问题标题】:How do I encode Unicode character codes in a PowerShell string literal?如何在 PowerShell 字符串文字中编码 Unicode 字符代码?
【发布时间】:2010-11-06 14:25:37
【问题描述】:

如何在 PowerShell 字符串中对 Unicode 字符 U+0048 (H) 进行编码?

在 C# 中我会这样做:"\u0048",但这似乎不适用于 PowerShell。

【问题讨论】:

  • 你的输出编码设置是什么? ($OutputEncoding)
  • 这是 us-ascii。但是 U+0048 应该是可编码的。我实际上是在尝试编码转义字符(U+001B)。

标签: powershell unicode string-literals unicode-literals


【解决方案1】:

将 '\u' 替换为 '0x' 并将其转换为 System.Char:

PS > [char]0x0048
H

您还可以使用“$()”语法将 Unicode 字符嵌入到字符串中:

PS > "Acme$([char]0x2122) Company"
AcmeT Company

其中 T 是 PowerShell 对非注册商标字符的表示。

【讨论】:

  • 你甚至可以写一个小函数:function C($n) {[char][int]"0x$n"}。您可以在字符串中使用如下:“$(C 48)ello World.”不理想,但可能更接近 \u 逃逸。
  • 当您想将 unicode [char] 传递给函数时,这也适用。感谢您的帮助。
  • 我知道这个话题已经有 2.5 年的历史了,但是根据@Joey 的评论,您甚至可以制作一个名为\u 的函数。它与乔伊的相同,只是名称不同。所以函数是function \u($n) {[char][int]"0x$n"}。你调用它的方式就像 C# 一样,只是你需要在函数名和数字之间有一个空格。所以\u 0048 返回H
【解决方案2】:

根据文档,PowerShell Core 6.0 增加了对这个转义序列的支持:

PS> "`u{0048}"
H

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_special_characters?view=powershell-6#unicode-character-ux

【讨论】:

    【解决方案3】:

    也许这不是 PowerShell 方式,但这就是我所做的。我觉得它更干净。

    [regex]::Unescape("\u0048") # Prints H
    [regex]::Unescape("\u0048ello") # Prints Hello
    

    【讨论】:

      【解决方案4】:

      使用 PowerShell 的另一种方式。

      $Heart = $([char]0x2665)
      $Diamond = $([char]0x2666)
      $Club = $([char]0x2663)
      $Spade = $([char]0x2660)
      Write-Host $Heart -BackgroundColor Yellow -ForegroundColor Magenta
      

      使用命令help Write-Host -Full 阅读所有相关信息。

      【讨论】:

      • Shay Levy's answer above 已经展示了如何使用[char]0x2665。事实上,这是效率低得多,因为您为每个变量创建一个新的子shell,而不是直接分配:$Heart = [char]0x2665
      【解决方案5】:

      要使其适用于 BMP 之外的字符,您需要使用 Char.ConvertFromUtf32()

      'this is my favourite park ' + [char]::ConvertFromUtf32(0x1F3DE) + 
      '. It is pretty sweet ' + [char]::ConvertFromUtf32(0x1F60A)
      

      【讨论】:

      • 好像有人不明白 Unicode 和 BMP 是什么意思
      【解决方案6】:

      对于我们这些仍在使用 5.1 并希望使用高阶 Unicode 字符集(这些答案都不起作用)的人,我制作了这个函数,以便您可以像这样简单地构建字符串:

      'this is my favourite park ',0x1F3DE,'. It is pretty sweet ',0x1F60A | Unicode
      

      #takes in a stream of strings and integers,
      #where integers are unicode codepoints,
      #and concatenates these into valid UTF16
      Function Unicode {
          Begin {
              $output=[System.Text.StringBuilder]::new()
          }
          Process {
              $output.Append($(
                  if ($_ -is [int]) { [char]::ConvertFromUtf32($_) }
                  else { [string]$_ }
              )) | Out-Null
          }
          End { $output.ToString() }
      }
      

      请注意,让这些显示在您的控制台中的是 whole other problem,但如果您要输出到 Outlook email 或 Gridview(如下),它将正常工作(因为 utf16 是 .NET 接口的本机)。

      这也意味着如果您更习惯使用十进制,您也可以很容易地输出纯控制(不一定是 unicode)字符,因为您实际上不需要使用 0x(十六进制)语法来生成整数。 'hello',32,'there' | Unicode 会在这两个词之间添加一个non-breaking space,就像您改为使用0x20 一样。

      【讨论】:

      • [char]::ConvertFromUtf32 从 .NET 2.1 开始可用,因此您不需要如此复杂的功能
      • 哦,太好了。该功能仍然是必需的,我不会在需要"`u{}" 时写[char]blahblahblah,但它确实简化了if
      • 除了$_ -shr 11,应该使用[int][math]::Floor($_ / 0x400)($_ -band 0x3FF) -bor 0xDC00,而不是[char]($_ % 0x400 + 0xDC00)
      • 我认为这很明显,因为它是一个很好的偶数十六进制数,哦,好吧。现在 .NET 可以处理总体问题并不重要
      【解决方案7】:

      请注意,像? 这样的某些字符可能需要打印“双符文”:

         PS> "C:\foo\bar\$([char]0xd83c)$([char]0xdf0e)something.txt"
      

      将打印:

         C:\foo\bar\?something.txt
      

      您可以在此处的“unicode escape”行中找到这些“符文”:

         https://dencode.com/string
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-02
        • 1970-01-01
        • 1970-01-01
        • 2019-07-14
        • 1970-01-01
        • 2016-05-21
        相关资源
        最近更新 更多