Unicodeの仕様に基づいた大文字小文字を変換するには 2014/12/08
アルファベット26文字以外の大文字小文字の変換ルールは意外と複雑で、以下は言語ごとにどう変換してくれるかの比較。
Unicodeの大文字小文字の変換ルールに関しては Unicodeの大文字と小文字のまとめも参照。
試した言語の中ではPythonが一番優秀のようだ。
Scala 2014/11/13
Scalaでの例
println("heLLO");
// => heLLO
// 文字列中のすべての文字を小文字にする
println("heLLO".toLowerCase);
// => hello
// 文字列の先頭の文字を大文字にし、2文字目以降はそのままにする
// 2文字目以降を小文字にすることはしない
println("heLLO".capitalize);
// => HeLLO
// 文字列中のすべての文字を大文字にする
println("heLLO".toUpperCase);
// => HELLO
println("\u00E6\u00E6\u00E6");
// => æææ
// 7ビットを超えるUnicodeの文字も正しく変換する
println("\u00E6\u00E6\u00E6".capitalize);
// => Æææ
// 7ビットを超えるUnicodeの文字も正しく変換する
println("\u00E6\u00E6\u00E6".toUpperCase);
// => ÆÆÆ
println("\u00DF");
// => ß
// "Ss" が期待されるが、変換しない
println("\u00DF\u00DF\u00DF".capitalize);
// => ß
// 大文字への変換であれば、2文字以上への変換もする
println("\u00DF".toUpperCase);
// => SS
println("\uFB01ght");
// => fight
println("\uFB01ght".toLowerCase);
// => fight
// "Fight" が期待されるが、なぜかこれは変換しない
println("\uFB01ght".capitalize);
// => fight
// 大文字への変換であれば、リガチャーも分解して変換する
println("\uFB01ght".toUpperCase);
// => FIGHT
println("\u03A3\u03A3\u03A3");
// => ΣΣΣ
// ギリシャ文字シグマ小文字は単語の最後では形が違うが、正しく変換する
println("\u03A3\u03A3\u03A3".toLowerCase);
// => σσς
// 1文字の場合は語末形にはならない
println("\u03A3".toLowerCase);
// => σ
// 1文字目はハンガリー語で1文字として扱われる"dz"
println("\u01F3s\u00FAsz");
// => dzsúsz
println("\u01F3s\u00FAsz".toLowerCase);
// => dzsúsz
// "Dzsúsz" が期待されるが、"dz"全体を大文字にしてしまい、正しく変換しない
println("\u01F3s\u00FAsz".capitalize);
// => DZsúsz
// 大文字への変換であれば、正しく変換する
println("\u01F3s\u00FAsz".toUpperCase);
// => DZSÚSZ
これは以下の環境での実行例である。
$ java -version
java version "1.7.0_21"
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)
$ scala -version
Scala code runner version 2.10.2 -- Copyright 2002-2013, LAMP/EPFL
PHP 2014/12/05
例
$str = "heLLO";
echo $str . "\n";
// => heLLO
echo mb_convert_case($str, MB_CASE_LOWER, "UTF-8") . "\n";
// => hello
echo mb_convert_case($str, MB_CASE_TITLE, "UTF-8") . "\n";
// => Hello
echo mb_convert_case($str, MB_CASE_UPPER, "UTF-8") . "\n";
// => HELLO
$str = "\xC3\xA6";
echo $str . "\n";
// => æ
echo mb_convert_case($str, MB_CASE_LOWER, "UTF-8") . "\n";
// => æ
echo mb_convert_case($str, MB_CASE_TITLE, "UTF-8") . "\n";
// => Æ
echo mb_convert_case($str, MB_CASE_UPPER, "UTF-8") . "\n";
// => Æ
$str = "\xC3\x9F";
echo $str . "\n";
// => ß
echo mb_convert_case($str, MB_CASE_LOWER, "UTF-8") . "\n";
// => ß
echo mb_convert_case($str, MB_CASE_TITLE, "UTF-8") . "\n";
// => ß
echo mb_convert_case($str, MB_CASE_UPPER, "UTF-8") . "\n";
// => ß
$str = "\xEF\xAC\x81ght";
echo $str . "\n";
// => fight
echo mb_convert_case($str, MB_CASE_LOWER, "UTF-8") . "\n";
// => fight
echo mb_convert_case($str, MB_CASE_TITLE, "UTF-8") . "\n";
// => fight
echo mb_convert_case($str, MB_CASE_UPPER, "UTF-8") . "\n";
// => fiGHT
$str = "\xCE\xA3\xCE\xA3\xCE\xA3";
echo $str . "\n";
// => ΣΣΣ
echo mb_convert_case($str, MB_CASE_LOWER, "UTF-8") . "\n";
// => σσσ
echo mb_convert_case($str, MB_CASE_TITLE, "UTF-8") . "\n";
// => Σσσ
echo mb_convert_case($str, MB_CASE_UPPER, "UTF-8") . "\n";
// => ΣΣΣ
$str = "\xC7\xB3s\xC3\xBAsz";
echo $str . "\n";
// => dzsúsz
echo mb_convert_case($str, MB_CASE_LOWER, "UTF-8") . "\n";
// => dzsúsz
echo mb_convert_case($str, MB_CASE_TITLE, "UTF-8") . "\n";
// => Dzsúsz
echo mb_convert_case($str, MB_CASE_UPPER, "UTF-8") . "\n";
// => DzSÚSZ
上記実行例のPHPのバージョンは5.5.3。
Python 2014/11/14
Python3での例
str = "heLLO"
print(str);
# => heLLO
# 文字列中のすべての文字を小文字にする
print(str.lower());
# => hello
# 文字列の先頭の文字を大文字にし、2文字目以降を小文字にする
print(str.title());
# => Hello
# 文字列中のすべての文字を大文字にする
print(str.upper());
# => HELLO
str = "\u00E6\u00E6\u00E6"
print(str);
# => æææ
print(str.lower());
# => æææ
# 7ビットを超えるUnicodeの文字も正しく変換する
print(str.title());
# => Æææ
# 7ビットを超えるUnicodeの文字も正しく変換する
print(str.upper());
# => ÆÆÆ
str = "\u00DF" # ß
print(str);
# => ß
print(str.lower());
# => ß
# 1文字から2文字への変換もする
print(str.title());
# => Ss
# 1文字から2文字への変換もする
print(str.upper());
# => SS
str = "\uFB01ght"
print(str);
# => fight
print(str.lower());
# => fight
# リガチャも2文字に分解した上で、1文字目のみを大文字に変換する
print(str.title());
# => Fight
# 全部大文字にする場合もリガチャを分解する
print(str.upper());
# => FIGHT
str = "\u03A3\u03A3\u03A3"
print(str);
# => ΣΣΣ
# ギリシャ文字シグマ小文字は単語の最後では形が違うが、正しく変換する
print(str.lower());
# => σσς
# 1文字の場合は語末形にはならない
str = "\u03A3"
print(str.lower());
# => σ
# 1文字目はハンガリー語で1文字として扱われる"dz"
str = "\u01F3s\u00FAsz"
print(str);
# => dzsúsz
print(str.lower());
# => dzsúsz
# 本当の1文字目のみを大文字に変換する
print(str.title());
# => Dzsúsz
# 全体を大文字に変換する
print(str.upper());
# => DZSÚSZ
JavaScript 2014/12/08
1文字目だけを大文字にするための便利なメソッドはないようだ。
例
var str = "heLLO";
console.log(str);
// => heLLO
// 文字列中のすべての文字を小文字にする
console.log(str.toLowerCase());
// => hello
// 文字列中のすべての文字を大文字にする
console.log(str.toUpperCase());
// => HELLO
str = "\u00E6\u00E6\u00E6";
console.log(str);
// => æææ
// 7ビットを超えるUnicodeの文字も正しく変換する
console.log(str.toUpperCase());
// => ÆÆÆ
str = "\u00DF";
console.log(str);
// => ß
// 大文字への変換であれば、2文字以上への変換もする
console.log(str.toUpperCase());
// => SS
// Firefoxでは ß のままになってしまう
str = "\uFB01ght";
console.log(str);
// => fight
console.log(str.toLowerCase());
// => fight
// 大文字への変換であれば、リガチャーも分解して変換する
console.log(str.toUpperCase());
// => FIGHT
str = "\u03A3\u03A3\u03A3";
console.log(str);
// => ΣΣΣ
// ギリシャ文字シグマ小文字は単語の最後では形が違うが、正しく変換する
console.log(str.toLowerCase());
// => σσς
// Firefoxでは語末形にしてくれず3文字とも同じになってしまう
str = "\u03A3";
// 1文字の場合も語末形にはなる
console.log(str.toLowerCase());
// => ς
// Firefoxでは語末形にしてくれない
str = "\u01F3s\u00FAsz";
// 1文字目はハンガリー語で1文字として扱われる"dz"
console.log(str);
// => dzsúsz
console.log(str.toLowerCase());
// => dzsúsz
console.log(str.toUpperCase());
// => DZSÚSZ
上記実行例は nodejs v0.10.15, Chrome 40, Firefox 32 で確認。