👻

【PowerShell】文字とユニコードエスケープシーケンスの相互変換

2023/07/11に公開

PowerShell はユニコードエスケープシーケンスをサポートする。

> "`u{3042}"

調べた時点ではバイト列のエスケープシーケンスはサポートされていない。

> "`xe3`x81`x82"
xe3x81x82

U+0000 から U+FFFF の範囲は [char] から文字列オブジェクトを生成できる。

> [char]0x3042
あ

[char] は U+10000 から U+10FFFF の範囲のコードポイントは利用できない。

> [char]0x1F436
InvalidArgument: Cannot convert value "128054" to type "System.Char". Error: "Value was either too large or too small for a character."

代わりに [Text.Rune] から文字列オブジェクトを生成する。

> [String]([Text.Rune]0x1F436)
🐶
> ([Text.Rune]0x1F436).ToString()
🐶

複数のコードポイントを指定することもできる。

> [String]([Text.Rune]0x1F436, [Text.Rune]0x1F408)
🐶 🐈

+ 演算子を使って文字列を連結できる。

> [char]0x3042 + "いうえお"
あいうえお
> [String]([Text.Rune]0x1F436) + "🐈"
🐶🐈

次に文字からコードポイントやユニコードエスケープシーケンスを求める。

U+0000..U+FFFF の範囲の文字であればインデックスアクセスを利用できる。

> "{0:x}" -f [int]"あ"[0]
3042
> "``u{{{0:x}}}" -f [int]"あ"[0]
`u{3042}

U+10000..U+10FFFF の範囲の文字も扱う場合、EnumerateRunes メソッドを使う。

> "``u{{{0:x}}}" -f [int]"🐶🐈".EnumerateRunes().Value[0]
`u{1f436}

複数の文字をまとめて処理する場合、foreach ループが使える。

> foreach ($char in "🐶🐈".EnumerateRunes()) { write-host -n ('\u{{{0:x}}}' -f $char.value) }
\u{1f436}\u{1f408}

ほかのプログラミング言語で使うためのバイト単位のエスケープシーケンスの生成も取り上げる。getBytes メソッドを使う。

> [Text.Encoding]::UTF8.GetBytes("あ") | % { write-host -n ('\x{0:x}' -f $_ ) }
\xe3\x81\x82

バイト単位のエスケープシーケンスから文字列を生成するには FromHexString メソッドを使う。

> [Text.Encoding]::UTF8.GetString([Convert]::FromHexString('\xe3\x81\x82' -replace '\\x'))

Discussion