如何将西里尔字母转换成utf16
How to convert cyrillic into utf16
tl;dr 有没有办法将哈希表中存储的西里尔字母转换为 UTF-16?
喜欢кириллица
变成\u043a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u0430
我需要导入文件,将其解析为 id
和 value
,然后将其转换为 .json,现在我正在努力寻找一种方法来转换 value
转换为 utf 代码。
是的,这是需要的
cyrillic.txt:
1 кириллица
PH:
clear-host
foreach ($line in (Get-Content C:\Users\users\Downloads\cyrillic.txt)){
$nline = $line.Split(' ', 2)
$properties = @{
'id'= $nline[0] #stores "1" from file
'value'=$nline[1] #stores "кириллица" from file
}
$temp+=New-Object PSObject -Property $properties
}
$temp | ConvertTo-Json | Out-File "C:\Users\user\Downloads\data.json"
输出:
[
{
"id": "1",
"value": "кириллица"
},
]
需要:
[
{
"id": "1",
"value": "\u043a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u0430"
},
]
此时作为 PH 的新手,我什至不知道如何正确搜索它
肯定有一种更简单的方法可以做到这一点,但这对你有用:
$temp = foreach ($line in (Get-Content -Path 'C:\Users\users\Downloads\cyrillic.txt')){
$nline = $line.Split(' ', 2)
# output an object straight away so it gets collected in variable $temp
[PsCustomObject]@{
id = $nline[0] #stores "1" from file
value = (([system.Text.Encoding]::BigEndianUnicode.GetBytes($nline[1]) |
ForEach-Object {'{0:x2}' -f $_ }) -join '' -split '(.{4})' -ne '' |
ForEach-Object { '\u{0}' -f $_ }) -join ''
}
}
($temp | ConvertTo-Json) -replace '\\u', '\u' | Out-File 'C:\Users\user\Downloads\data.json'
使用 .ToCharArray()
更简单:
$temp = foreach ($line in (Get-Content -Path 'C:\Users\users\Downloads\cyrillic.txt')){
$nline = $line.Split(' ', 2)
# output an object straight away so it gets collected in variable $temp
[PsCustomObject]@{
id = $nline[0] #stores "1" from file
value = ($nline[1].ToCharArray() | ForEach-Object {'\u{0:x4}' -f [uint16]$_ }) -join ''
}
}
($temp | ConvertTo-Json) -replace '\\u', '\u' | Out-File 'C:\Users\user\Downloads\data.json'
值 "кириллица"
将转换为 \u043a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u0430
基于 Jeroen Mostert 的有用评论,假设输入文件不包含 NUL
个字符(这通常是 text 个文件):
# Sample value pair; loop over file lines omitted for brevity.
$nline = '1 кириллица'.Split(' ', 2)
$properties = [ordered] @{
id = $nline[0]
# Insert aux. NUL characters before the 4-digit hex representations of each
# code unit, to be removed later.
value = -join ([uint16[]] [char[]] $nline[1]).ForEach({ "`0{0:x4}" -f $_ })
}
# Convert to JSON, then remove the escaped representations of the aux. NUL chars.,
# resulting in proper JSON escape sequences.
# Note: ... | Out-File ... omitted.
(ConvertTo-Json @($properties)) -replace '\u0000', '\u'
输出(通过管道传输到 ConvertFrom-Json
以验证其是否有效):
[
{
"id": "1",
"value": "\u043a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u0430"
}
]
解释:
[uint16[]] [char[]] $nline[1]
将存储在 $nline[1]
中的字符串的 [char]
实例转换为底层 UTF-16 代码单元(.NET [char]
是编码 Unicode 代码点的无符号 16 位整数)。
- 请注意,这甚至适用于代码点高于
0xFFFF
的 Unicode 字符,即太大而无法放入 [uint16]
。 so-called BMP(基本多语言平面)之外的此类字符,例如</code>,简单表示为<em>对</em> UTF-16代码单元,so-called <em>代理对</em> ,JSON 处理器应该识别(<a href="https://docs.microsoft.com/powershell/module/microsoft.powershell.utility/convertfrom-json" rel="nofollow noreferrer"><code>ConvertFrom-Json
可以识别)。
- 但是,在Windows这样的字符上。可能无法 正确呈现 ,具体取决于您的控制台 window 的字体。最安全的选择是使用 Windows Terminal, available in the Microsoft Store
对 .ForEach()
array method 的调用处理每个结果代码单元:
"`0{0:x4}" -f $_
使用 expandable string to create a string that starts with a NUL
character ("`0"
), followed by a 4-digit hex. representation (x4
) of the code unit at hand, created via -f
, the format operator.
- 这种将最终应该
\u
前缀临时替换为NUL
字符的技巧是必需的,因为嵌入字符串值中的逐字 \
在其 JSON 表示中总是 加倍 ,假设 \
充当转义字符在 JSON.
结果类似于 "<NUL>043a"
,ConvertTo-Json
转换如下,因为它必须将每个 NUL
字符转义为 \u0000
:
"\u0000043a"
然后可以将 ConvertTo-Json
的结果简单地通过替换 \u0000
转换为所需的转义序列(转义为 \u0000
以便与 regex-based -replace
oeprator) 与 \u
,例如:
"\u0000043a" -replace '\u0000', '\u' # -> "\u043a", i.e. к
这里有一种方法,只需将其保存到 utf16be 文件,然后读出字节并格式化,跳过前 2 个字节,即 bom (\ufeff)。 $_ 本身不起作用。请注意,有 two utf16 编码具有不同的字节顺序,big endian 和 little endian。西里尔字母的范围是 U+0400..U+04FF。添加-nonewline.
'кириллица' | set-content utf16be.txt -encoding BigEndianUnicode -nonewline
$list = get-content utf16be.txt -Encoding Byte -readcount 2 |
% { '\u{0:x2}{1:x2}' -f $_[0],$_[1] } | select -skip 1
-join $list
\u043a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u0430
tl;dr 有没有办法将哈希表中存储的西里尔字母转换为 UTF-16?
喜欢кириллица
变成\u043a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u0430
我需要导入文件,将其解析为 id
和 value
,然后将其转换为 .json,现在我正在努力寻找一种方法来转换 value
转换为 utf 代码。
是的,这是需要的
cyrillic.txt:
1 кириллица
PH:
clear-host
foreach ($line in (Get-Content C:\Users\users\Downloads\cyrillic.txt)){
$nline = $line.Split(' ', 2)
$properties = @{
'id'= $nline[0] #stores "1" from file
'value'=$nline[1] #stores "кириллица" from file
}
$temp+=New-Object PSObject -Property $properties
}
$temp | ConvertTo-Json | Out-File "C:\Users\user\Downloads\data.json"
输出:
[
{
"id": "1",
"value": "кириллица"
},
]
需要:
[
{
"id": "1",
"value": "\u043a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u0430"
},
]
此时作为 PH 的新手,我什至不知道如何正确搜索它
肯定有一种更简单的方法可以做到这一点,但这对你有用:
$temp = foreach ($line in (Get-Content -Path 'C:\Users\users\Downloads\cyrillic.txt')){
$nline = $line.Split(' ', 2)
# output an object straight away so it gets collected in variable $temp
[PsCustomObject]@{
id = $nline[0] #stores "1" from file
value = (([system.Text.Encoding]::BigEndianUnicode.GetBytes($nline[1]) |
ForEach-Object {'{0:x2}' -f $_ }) -join '' -split '(.{4})' -ne '' |
ForEach-Object { '\u{0}' -f $_ }) -join ''
}
}
($temp | ConvertTo-Json) -replace '\\u', '\u' | Out-File 'C:\Users\user\Downloads\data.json'
使用 .ToCharArray()
更简单:
$temp = foreach ($line in (Get-Content -Path 'C:\Users\users\Downloads\cyrillic.txt')){
$nline = $line.Split(' ', 2)
# output an object straight away so it gets collected in variable $temp
[PsCustomObject]@{
id = $nline[0] #stores "1" from file
value = ($nline[1].ToCharArray() | ForEach-Object {'\u{0:x4}' -f [uint16]$_ }) -join ''
}
}
($temp | ConvertTo-Json) -replace '\\u', '\u' | Out-File 'C:\Users\user\Downloads\data.json'
值 "кириллица"
将转换为 \u043a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u0430
基于 Jeroen Mostert 的有用评论,假设输入文件不包含 NUL
个字符(这通常是 text 个文件):
# Sample value pair; loop over file lines omitted for brevity.
$nline = '1 кириллица'.Split(' ', 2)
$properties = [ordered] @{
id = $nline[0]
# Insert aux. NUL characters before the 4-digit hex representations of each
# code unit, to be removed later.
value = -join ([uint16[]] [char[]] $nline[1]).ForEach({ "`0{0:x4}" -f $_ })
}
# Convert to JSON, then remove the escaped representations of the aux. NUL chars.,
# resulting in proper JSON escape sequences.
# Note: ... | Out-File ... omitted.
(ConvertTo-Json @($properties)) -replace '\u0000', '\u'
输出(通过管道传输到 ConvertFrom-Json
以验证其是否有效):
[
{
"id": "1",
"value": "\u043a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u0430"
}
]
解释:
[uint16[]] [char[]] $nline[1]
将存储在$nline[1]
中的字符串的[char]
实例转换为底层 UTF-16 代码单元(.NET[char]
是编码 Unicode 代码点的无符号 16 位整数)。- 请注意,这甚至适用于代码点高于
0xFFFF
的 Unicode 字符,即太大而无法放入[uint16]
。 so-called BMP(基本多语言平面)之外的此类字符,例如</code>,简单表示为<em>对</em> UTF-16代码单元,so-called <em>代理对</em> ,JSON 处理器应该识别(<a href="https://docs.microsoft.com/powershell/module/microsoft.powershell.utility/convertfrom-json" rel="nofollow noreferrer"><code>ConvertFrom-Json
可以识别)。 - 但是,在Windows这样的字符上。可能无法 正确呈现 ,具体取决于您的控制台 window 的字体。最安全的选择是使用 Windows Terminal, available in the Microsoft Store
- 请注意,这甚至适用于代码点高于
对
.ForEach()
array method 的调用处理每个结果代码单元:"`0{0:x4}" -f $_
使用 expandable string to create a string that starts with aNUL
character ("`0"
), followed by a 4-digit hex. representation (x4
) of the code unit at hand, created via-f
, the format operator.- 这种将最终应该
\u
前缀临时替换为NUL
字符的技巧是必需的,因为嵌入字符串值中的逐字\
在其 JSON 表示中总是 加倍 ,假设\
充当转义字符在 JSON.
- 这种将最终应该
结果类似于
"<NUL>043a"
,ConvertTo-Json
转换如下,因为它必须将每个NUL
字符转义为\u0000
:"\u0000043a"
然后可以将
ConvertTo-Json
的结果简单地通过替换\u0000
转换为所需的转义序列(转义为\u0000
以便与 regex-based-replace
oeprator) 与\u
,例如:"\u0000043a" -replace '\u0000', '\u' # -> "\u043a", i.e. к
这里有一种方法,只需将其保存到 utf16be 文件,然后读出字节并格式化,跳过前 2 个字节,即 bom (\ufeff)。 $_ 本身不起作用。请注意,有 two utf16 编码具有不同的字节顺序,big endian 和 little endian。西里尔字母的范围是 U+0400..U+04FF。添加-nonewline.
'кириллица' | set-content utf16be.txt -encoding BigEndianUnicode -nonewline
$list = get-content utf16be.txt -Encoding Byte -readcount 2 |
% { '\u{0:x2}{1:x2}' -f $_[0],$_[1] } | select -skip 1
-join $list
\u043a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u0430