web-dev-qa-db-ja.com

16進コード(\ x)とUnicode(\ u)文字の違いは何ですか?

_?Quotes_から:

_\xnn   character with given hex code (1 or 2 hex digits)  
\unnnn Unicode character with given code (1--4 hex digits)
_

Unicode文字に1桁または2桁しかない場合、これらの文字は同じであると予想されます。実際、_?Quotes_ヘルプページの例の1つに以下が示されています。

_"\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21"
## [1] "Hello World!"
"\u48\u65\u6c\u6c\u6f\u20\u57\u6f\u72\u6c\u64\u21"
## [1] "Hello World!"
_

ただし、Linuxでは、ポンド記号を印刷しようとすると、

_cat("\ua3")
## £
cat("\xa3")
## �
_

つまり、_\x_ 16進コードが正しく表示されません。 (この動作は、私が試したどのロケールでも持続しました。)Windows 7では、両方のバージョンにポンド記号が表示されます。

Linuxで整数に変換してから逆に変換すると、ポンド記号が正しく表示されます。

_cat(intToUtf8(utf8ToInt("\xa3")))
## £
_

ちなみに、utf8ToInt("\xa3")NAを返すため、これはWindowsでは機能しません。

一部の_\x_文字は、WindowsではNAを返しますが、Linuxではエラーをスローします。例えば:

_utf8ToInt("\xf0")
## Error in utf8ToInt("\xf0") : invalid UTF-8 string
_

(_"\uf0"_は有効な文字です。)

これらの例は、_\x_と_\u_の形式の文字にはいくつかの違いがあることを示しています。これらはOS固有のようですが、定義方法にはロジックがありません。

これら2つの文字形式の違いは何ですか?

22
Richie Cotton

エスケープシーケンス\xNNは生のバイトNNを文字列に挿入しますが、\uNNは、UnicodeコードポイントNNのUTF-8バイトをUTF-8文字列に挿入します。

> charToRaw('\xA3')
[1] a3
> charToRaw('\uA3')
[1] c2 a3

これら2つのタイプのエスケープシーケンスを同じ文字列に混在させることはできません。

> '\ua3\xa3'
Error: mixing Unicode and octal/hex escapes in a string is not allowed

これは、エスケープシーケンスが文字列のエンコードも定義するためです。 \uNNシーケンスは、文字列全体のエンコーディングを明示的に「UTF-8」に設定しますが、\xNNは、デフォルトの「不明」(別名、ネイティブ)エンコーディングのままにします。

> Encoding('\xa3')
[1] "unknown"
> Encoding('\ua3')
[1] "UTF-8"

これは、適切な出力エンコーディング(コンソールなど)に変換する必要があるため、文字列を印刷するときに重要になります。エンコードが定義された文字列は、適切に変換できます(enc2native)。ただし、「不明な」エンコーディングの場合は、そのまま出力されます。

  • Linuxでは、コンソールはおそらくUTF-8テキストを想定しており、0xA3は有効なUTF-8シーケンスではありません。「�」が返されます。
  • Windowsでは、コンソールはおそらくWindows-1252テキストを想定しており、0xA3は「£」の正しいエンコードです。これが表示されます。 (文字列が\uA3、UTF-8からWindows-1252への変換が行われます。

エンコードが明示的に設定されている場合、Linuxで適切な変換が行われます。

> s <- '\xa3'
> Encoding(s) <- 'latin1'
> cat(s)
£
22
一二三