Unicodeエスケープで文字列リテラルを書くには
Java / Scala 2014/11/06
Java/ScalaにはUnicodeエスケープという仕組みがある。
Unicodeエスケープは、文字列リテラルの機能ではなく、
Java/Scalaソースコードをコンパイラがトークンに分割する前の処理として機能する。従って、"\u005C"
というのはコンパイルエラーになる。
\u005C
を \
に変換してからトークンに分割しようとするが、
"\"
は文字列が終了していないためである。文字列リテラルではなく、コンパイラの前処理として働くUnicodeエスケープは、他の言語にはあまり見られない。
16ビットを超える文字(Unicodeの拡張領域)は、サロゲートペアで2つの16ビットに分割する必要がある。
以下は、微妙なケースの例(Scalaでのコードだが、Javaでも同じ結果であった。 Java 1.7.0_05, Scala 2.9.2 で確認)
println("\u3044"); // => い
println("\\u3044"); // => \u3044
println("\\\u3044"); // => \い
println("\\\\u3044"); // => \\u3044
println("\uu3044"); // => い
println("\uuu3044"); // => い
println("\\\uu3044"); // => \い
u
が連続する場合の解釈がちょっと不思議。
PHP 2015/11/25
PHPはUnicodeにネイティブには対応しておらず、 8ビットを超える文字(U+0100以上)を文字単位で直接16進数で表記する手段がない。 UTF8でソースコードを書いている場合は、文字列もUTF8にしてバイト単位で16進数表記することは可能。
// \u1F30D 地球の絵文字は4バイトに分割して表記
$str = "\xF0\x9F\x8C\x8D";
Unicodeエスケープを復元する関数を書いておけば、 Unicodeエスケープを使って文字列を表現することもできなくはない。
Python 2015/06/18
\u
hhhh (4桁)または \U00
hhhhhh (8桁)の形式で16進数表記できる。
16ビットまでの文字(基本多言語面)は2つの形式のどちらも使えるが、
16ビットを超える文字(拡張領域)は16進数で4桁を超えるので、大文字の \U00
hhhhhh の形式しか使えない。
大文字の \U00
hhhhhh の形式は16進数8桁書かないといけなくて、
Unicodeは6桁で十分なので、無駄な感じがする。
Python2ではUnicode文字列リテラル(u"..."
)の中でのみ使用可能。
Python2での、u"..."
以外の文字列ではエスケープされずそのまま文字列になる。
raw文字列 r"..."
の形式ではPython2でもPython3でもこのエスケープは使えない。
Python2での例
print u"\u5730\u7403\U0001F30D"
# => 地球🌍
# 3文字目は地球の絵文字
Python3での例
print("\u5730\u7403\U0001F30D")
# => 地球🌍
# 3文字目は地球の絵文字
Ruby 2014/11/19
\u
hhhh または \u{
hhhhhh}
の形式で16進数表記できる。
\u
hhhh の形式では16進数4桁で表記する。\u{
hhhhh}
の形式では16進数2桁〜6桁で表記する。
16ビットまでの文字(基本多言語面)は2つの形式のどちらも使えるが、
16ビットを超える文字(拡張領域)は16進数で4桁を超えるので \u{
hhhhh}
の形式しか使えない。
また、\u{
hhhhh}
の形式では{}
の中にスペース区切りで複数の文字をまとめて書くこともできる。
例
p "\u{5730 7403 1F30D}"
# => "地球🌍"
# 3文字目は地球の絵文字