我正在尝试创建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代码点0xc3b1
和0xc391
实际上是与0xc3 0xb1
和0xc3 91
相对应的真实代码点的2字节UTF-8编码(ñ
和Ñ
): 0xf1
和 0xd1
至于:
[convert]::toChar(0x91)
似乎未使用给定的代码点
[char]
(十进制0x91
)生成145
实例: [int] [convert]::toChar(0x91) # -> 145 (0x91)
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/