powershell - Powershell,无法输入带有某些非ASCII字符的哈希表键(在脚本中)

标签 powershell utf-8 character-encoding char hashtable

我正在尝试创建PowerShell哈希表,以将非ASCII(UTF8)字符转换为它们的ASCII外观。
以下是两个哈希表条目作为示例:'ñ'='n''Ñ'='N'
编者注:在同一个哈希表文字(@{ 'ñ'='n'; 'Ñ'='N' })中使用这两个条目将不起作用,因为PowerShell将哈希表与不区分大小写的键查找一起使用,因此将'ñ''Ñ'视为重复键并进行投诉。但是,这只是手头的问题。
第一个有效:'ñ'0xc3b1。第二个不起作用:'Ñ'是PowerShell不接受的0xc391。 (问题似乎是0x91在可接受的powershell字符范围之外。)
该问题的一个简单示例是:

$c = [convert]::toChar(0x91)
这导致$c的值为0x3f而不是0x91。所以我该怎么做才能将'Ñ'='N'放入
哈希表或值为0x91的字符?我已经花了几个小时阅读网页并进行实验。

最佳答案

注意:默认情况下,由于使用不区分大小写的查找,PowerShell哈希表不支持仅是另一个的大小写变体的键。因此,ñÑ-前者是后者的小写版本-不能同时用作键-参见底部。

在内存中,所有PowerShell字符串都是UTF-16 .NET字符串,它们能够表示所有Unicode字符,因此在哈希表中使用诸如Ñ这样的字符作为键不是问题。
您描述的问题仅在PowerShell假设由于字符编码错误而误解了从文件读取的源代码时出现。
您的症状表明您的源代码是UTF-8编码的,但是该文件没有BOM,这会导致Windows PowerShell(但幸运的是,不再是PowerShell [Core] v6 +)将文件误解为基于系统的 Activity 旧版ANSI代码页(例如,美式英语系统上的Windows-1252),为单字节编码。
确保使用BOM表 [1]将源代码文件另存为UTF-8,这样您的问题就会消失。
您认为的Unicode代码点0xc3b10xc391实际上是与0xc3 0xb10xc3 91相对应的真实代码点的2字节UTF-8编码(ñÑ): 0xf1 0xd1

至于:

[convert]::toChar(0x91)


似乎未使用给定的代码点[char](十进制0x91)生成145实例:
  • 确实如此,即在内存中,您可以轻松地对其进行验证:
      [int] [convert]::toChar(0x91) # -> 145 (0x91)
    
  • 如果您错误地将内存中表示形式保存为ASCII编码,则只会得到0x3f-这是一个文字上的?字符(尝试[char] 0x3f):由于0x91不在Unicode的ASCII子范围内(从0x00变为0x7f ),则无法在输出文件中表示它,而是使用替代字符?

  • 请注意, PowerShell的哈希表是不区分大小写的,因此您不能拥有仅是另一个的大小写变体的键:
    # !! FAILS
    PS> @{ Ñ = 'LATIN CAPITAL LETTER N WITH TILDE'; ñ = 'LATIN SMALL LETTER N WITH TILDE' }
    ...  Duplicate keys 'ñ' are not allowed in hash literals.
    
    您必须直接使用.NET [hashtable]类型(System.Collections.Hashtable)创建区分大小写的哈希表:
    # Create case-SENSITIVE hash table:
    $ht = [hashtable]::new()
    $ht['ñ'] = 'LATIN SMALL LETTER N WITH TILDE' 
    $ht['Ñ'] = 'LATIN CAPITAL LETTER N WITH TILDE'
    
  • $ht现在具有2个条目,并且$ht['ñ']$ht['Ñ']区分大小写地检索值。
  • 相反,如果您使用$ht = @{},即将哈希表初始化为不区分大小写的常规哈希表,则您只会获得1个值'LATIN CAPITAL LETTER N WITH TILDE'的条目,因为第二个赋值$ht['Ñ'] =只是更新了不区分大小写的外观第一条语句创建的向上键。

  • [1]或者,使用UTF-16编码,该编码始终使用BOM。 UTF-16LE格式在PowerShell中被错误地称为Unicode

    关于powershell - Powershell,无法输入带有某些非ASCII字符的哈希表键(在脚本中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62616715/

    相关文章:

    php - 将 utf-8 数据库转换为 utf8mb4 时出现重复输入错误

    encoding - 如何从错误的编码中恢复文本?

    powershell - Powershell txt文件过滤

    powershell - 我如何允许 powershell 接受命名参数的空字符串?

    dart - 从utf8到latin1

    php - 在 HTML 内容中获取 "�"

    powershell - 使用 Powershell 获取所有 AD 用户的递归组成员身份

    powershell - Windows Server 2008和Windows XP上的Powershell?

    encoding - 字母表的明确二进制编码方案

    mysql - 使用 VB.net 在 MySQL 数据库中存储马拉地语(印度语言)数据