2007年9月 8日

Unicode の文字列をソースコードに埋め込む方法

Unicode の文字列をソースコードに埋め込む場合、直接 UTF-8 などで文字列を書く方法と、\uXXXX などのようにエスケープして表記する方法があります。後者の方法についてまとめてみました。

 

\uXXXX 形式の場合

Java, JavaScript, Python, C++, C (C99から) などの多くの言語では \uXXXX という表記 (universal character names) でUnicode の文字を文字列の中に埋め込めます。たとえば、「あいう」は "\u3042\u3044\u3046" となります。

\uXXXX で埋め込んだ文字がどのように解釈されるかは言語や処理系によって異なります。

gcc/g++ の場合、 -fexec-charset オプションで、実際に使う文字セット・エンコーディングを指定できます。デフォルトは UTF-8 です。たとえば -fexec-charset=shift_jis のように指定すると、\uXXXX で埋め込んだ文字は Shift_JIS の文字として解釈されます。

このとき、 \u9AD0 (髙) のように Shift_JIS に含まれない文字がソースコードに含まれる場合、次のようなエラーになります。

% cat u.cc
const char hashigo_taka[] = "\u9AD0";
% g++ -fexec-charset=shift_jis -c u.cc
u.cc:1: error: converting UCN to execution character set: Invalid or incomplete multibyte or wide character

Python の場合、Unicode の文字列を扱うには u'\u3042\u3044\u3046' のように先頭に u をつけます。Unicode の文字列を出力する際には LANG や LC_ALL などの環境変数を元に自動的に出力用のエンコーディングが選ばれます。自動処理がうまくいかないと次のようなエラーが起きます。

>>> print u'\u3042'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
UnicodeEncodeError: 'ascii' codec can't encode character u'\u3042' in position 0: ordinal not in range(128)

このような場合は encode() 関数を使って明示的に変換すれば OK です。

>>> print u'\u3042'.encode('utf-8')
あ

JavaScript の場合、document.write("\u3042\u0062\u0063") などによって出力された文字列はウェブページのエンコーディングに合わせてよきにはからわれます。

Java の場合、コメントの中の \uXXXX が解釈されるので要注意です。次のコードは 2 を出力します。

int a = 0;
// \u000a a = 2;
System.out.println(a); 

同じ理由により Windows のパス名をコメントに含めるとはまります。次のコードはコンパイルエラーです。

// c:\unittest

なお、どの言語の場合も \uXXXX 形式を用いる場合、コードポイントが 16ビットに収まらない文字は、サロゲートペア で指定する必要があります。たとえば U+2000B (𠀋) という漢字は "\uD840\uDC0B" と指定します。

\xXX 形式の場合

\uXXXX をサポートしていない言語や、\uXXXX をサポートしている言語でも Unicode の文字列をバイト列として埋め込みたい場合は \xXX 表記を使います。たとえば、「あいう」を UTF-8 のバイト列として埋め込むには "\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86" となります。

C/C++ の場合、\xXX に続けて 0-9, A-F, a-f が続くとコンパイルエラーになるので注意が必要です。\xXX を使う場合は文字列全体をエスケープした方がよいでしょう。

% cat x.cc
const char ab [] ="\x61b\n";
% g++ -c x.cc
x.cc:1: error: hex escape sequence out of range

\UXXXXXXXX 形式の場合

\UXXXXXXXX の形式では 32ビットで Unicode のコードポイントを指定できます。が、あまり使われていないようです。

\XXX 形式の場合

8進数を使う方法も考えられますが、個人的には好みではないので使いません。

まとめ

Unicode の文字列を16進数表記にエスケープしてソースコードに埋め込む方法をまとめました。Unicode の文字列をエスケープする JavaScript のページで、ブラウザ上で簡単にエスケープできます。