tl; dr 有沒有辦法將存盤在哈希表中的西里爾字母轉換為 UTF-16?喜歡кириллица成\u043a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u0430
我需要匯入檔案,將其決議為id然后value將其轉換為 .json,現在我正在努力尋找一種轉換value為 utf 代碼的方法。
是的,需要這樣
西里爾文.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 的新手,我什至不知道如何正確搜索它
uj5u.com熱心網友回復:
基于Jeroen Mostert的有用評論,假設輸入檔案不包含NUL字符(這通常是文本檔案的安全假設),以下作業穩健:
# 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]將[char]存盤的字串實體轉換$nline[1]為底層 UTF-16 代碼單元(.NET[char]是編碼 Unicode 代碼點的無符號 16 位整數)。- 請注意,這甚至適用于具有上述代碼點的 Unicode 字符
0xFFFF,即太大而無法放入[uint16]. 所謂的 BMP(基本多語言平面)之外的這些字符,例如??,簡單地表示為UTF-16 代碼單元對,即所謂的代理對,JSON 處理器應該識別(ConvertFrom-Json確實)。 - 但是,在Windows上這樣的字符。可能無法正確呈現,具體取決于您的控制臺視窗的字體。最安全的選擇是使用Microsoft Store 中提供的Windows Terminal
- 請注意,這甚至適用于具有上述代碼點的 Unicode 字符
.ForEach()對陣列方法的呼叫會處理每個生成的代碼單元:"`0{0:x4}" -f $_使用可擴展字串創建以NUL字符 ("`0") 開頭,后跟 4 位十六進制的字串。x4手頭代碼單元的表示( )-f,通過格式運算子創建。- 這種用字符臨時替換最終應該是逐字
\u前綴的技巧是必要的,因為嵌入在字串值中的逐字在其 JSON 表示中總是會加倍,因為它在 JSON 中充當轉義字符。NUL\\
- 這種用字符臨時替換最終應該是逐字
結果類似于
"<NUL>043a",它ConvertTo-Json轉換如下,因為它必須將每個NUL字符轉義為\u0000:"\u0000043a"
ConvertTo-Json然后可以將結果 from轉換為所需的轉義序列,只需將\u0000(轉義為\\u0000與基于正則運算式的操作-replace符一起使用)替換為\u,例如:"\u0000043a" -replace '\\u0000', '\u' # -> "\u043a", i.e. к
uj5u.com熱心網友回復:
這是一種方法,只需將其保存到 utf16be 檔案,然后讀出位元組,并對其進行格式化,跳過前 2 個位元組,即 bom (\ufeff)。$_ 本身不起作用。請注意,有兩種utf16 編碼具有不同的位元組順序,即大端和小端。西里爾字母的范圍是 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
uj5u.com熱心網友回復:
必須有一種更簡單的方法來執行此操作,但這可能對您有用:
$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
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/454133.html
