Unicode拡張領域の取り扱い
Java / Scala 2014/12/08
Unicodeエスケープは16ビットまでの文字しか書けないので、拡張領域の文字をUnicodeエスケープで書くにはサロゲートペアで2つの16ビットに分割する必要がある。
Scalaでの例
println("地球🌍"); // 3文字目は地球の絵文字
// => 地球🌍
val str = "\u5730\u7403\uD83C\uDF0D";
println(str);
// => 地球🌍
val len = str.length;
println(len);
// => 4
println(str.codePointCount(0, len));
// => 3
val str2 = "🌍";
println(str2.codePointAt(0));
// => 127757
val str3 = new String(Array(127757), 0, 1);
println(str3);
// => 🌍
PHP 2015/02/01
PHPではUnicodeをネイティブには対応しておらず、単なるバイト配列である。 UTF-8で文字列を処理するのであれば、UTF-8のバイナリを書けば Unicodeの拡張領域の文字もいちおうは書くことができる。
$str = "地球🌍"; // 3文字目は地球の絵文字
echo "$str\n";
// => 地球🌍
$str = "\xE5\x9C\xB0\xE7\x90\x83\xF0\x9F\x8C\x8D";
echo "$str\n";
// => 地球🌍
// strlen は文字数ではなくバイト配列の長さ
echo strlen($str) . "\n";
// => 10
Python 2014/11/08
Python3では文字列に直接拡張領域の文字を書くこともできるし、
\U00
hhhhhh の形式のエスケープシーケンスでも拡張領域の文字を使える。
拡張領域の文字を気にすることなく各種関数をそのまま使える。
Python3での例
str = "地球🌍" # 3文字目は地球の絵文字
print(str)
# => 地球🌍
str = "\u5730\u7403\U0001F30D"
print(str)
# => 地球🌍
print(len(str))
# => 3
str = "\U0001F30D"
print(ord(str))
# => 127757
print(chr(127757))
# => 🌍
str = "\u5730\u7403\U0001F30E\U0001F30D"
print(str.find("\U0001F30D"))
# => 3
Python2ではUnicodeのエスケープを使えるのはUnicode文字列リテラル(u"..."
)の中のみである。
chr
関数は8ビットを超えるUnicode文字を扱えず、代わりに unichr
関数を使う必要がある。
Python2での例
str = "地球🌍" # 3文字目は地球の絵文字
print(str)
# => 地球🌍
str = u"\u5730\u7403\U0001F30D"
print(str)
# => 地球🌍
print(len(str))
# => 3
str = u"\U0001F30D"
print(ord(str))
# => 127757
print(unichr(127757))
# => 🌍
str = u"\u5730\u7403\U0001F30E\U0001F30D"
print(str.find(u"\U0001F30D"))
# => 3
Ruby 2014/11/03
文字列には直接拡張領域の文字を書くこともできるし、
\u{
hhhhh}
の形式のエスケープシーケンスでも拡張領域の文字を使える。
p "地球🌍" # 3文字目は地球の絵文字
# => "地球🌍"
p "\u{5730 7403 1F30D}"
# => "地球🌍"
p "\u{5730 7403 1F30D}".length
# => 3
p "🌍".ord;
# => 127757
p 127757.chr("UTF-8")
# => "🌍"
p "\u{5730 7403 1F30E 1F30D}".index("\u{1F30D}")
# => 3
Perl 2014/11/02
use utf8;
と宣言しておけば、文字列には直接拡張領域の文字を書くこともできるし、
\x{
hhhhh}
の形式のエスケープシーケンスでも拡張領域の文字を使える。
use utf8;
use Encode qw/encode_utf8/;
print encode_utf8("地球🌍\n"); # 3文字目は地球の絵文字
# => 地球🌍
print encode_utf8("\x{5730}\x{7403}\x{1F30D}\n");
# => 地球🌍
print length("\x{5730}\x{7403}\x{1F30D}");
# => 3
print ord("🌍");
# => 127757
print encode_utf8(chr(127757));
# => 🌍
JavaScript 2014/12/08
Javaと同じく、Unicodeエスケープは16ビットまでの文字しか書けないので、拡張領域の文字をUnicodeエスケープで書くにはサロゲートペアで2つの16ビットに分割する必要がある。
console.log("地球🌍"); // 3文字目は地球の絵文字
// => 地球🌍
var str = "\u5730\u7403\uD83C\uDF0D";
console.log(str);
// => 地球🌍
var len = str.length;
console.log(len);
// => 4
上記実行例は nodejs v0.10.15 で確認。
サロゲートペアに対応した文字数取得などはJavaScriptには存在せず、以下のようなライブラリが必要。
javascript - でBMP以外のUnicode文字をきちんと扱う
http://blog.livedoor.jp/dankogai/archives/51861512.html