ToUpper() が存在しない場合、どのように記述しますか? i18n および L10n のボーナス ポイント
これによって引き起こされた好奇心: http://thedailywtf.com/Articles/The-Long-Way-toUpper.aspx
ToUpper() が存在しない場合、どのように記述しますか? i18n および L10n のボーナス ポイント
これによって引き起こされた好奇心: http://thedailywtf.com/Articles/The-Long-Way-toUpper.aspx
これがサンプル実装です;)
public static String upper(String s) {
if (s == null) {
return null;
}
final int N = s.length(); // Mind the optimization!
PreparedStatement stmtName = null;
PreparedStatement stmtSmall = null;
ResultSet rsName = null;
ResultSet rsSmall = null;
StringBuilder buffer = new StringBuilder (N); // Much faster than StringBuffer!
try {
conn = DBFactory.getConnection();
stmtName = conn.prepareStatement("select name from unicode.chart where codepoint = ?");
// TODO Optimization: Maybe move this in the if() so we don't create this
// unless there are uppercase characters in the string.
stmtSmall = conn.prepareStatement("select codepoint from unicode.chart where name = ?");
for (int i=0; i<N; i++) {
int c = s.charAt(i);
stmtName.setInt(1, c);
rsName = stmtName.execute();
if (rsName.next()) {
String name = rsName.getString(1);
if (name.contains(" SMALL ")) {
name = name.replaceAll(" SMALL ", " CAPITAL ");
stmtSmall.setString(1, name);
rsSmall = stmtSmall.execute();
if (rsSmall.next()) {
c = rsSmall.getInt(1);
}
rsSmall = DBUtil.close(rsSmall);
}
}
rsName = DBUtil.close(rsName);
}
}
finally {
// Always clean up
rsSmall = DBUtil.close(rsSmall);
rsName = DBUtil.close(rsName);
stmtSmall = DBUtil.close(stmtSmall);
stmtName = DBUtil.close(stmtName);
}
// TODO Optimization: Maybe read the table once into RAM at the start
// Would waste a lot of memory, though :/
return buffer.toString();
}
;)
注: unicode.orgで見つけることができる Unicode チャートには、文字/コード ポイントの名前が含まれています。この文字列には、大文字の " SMALL " が含まれます (空白に注意してください。そうしないと、"SMALLER" などと一致する可能性があります)。これで、「SMALL」を「CAPITAL」に置き換えた類似の名前を検索できます。見つかった場合は、大文字バージョンを見つけたことになります。
SOが1回の投稿でUnicodeテーブルのサイズを処理できるとは思わない:)
残念ながら、文字ごとに char.ToUpper() を実行するだけでは簡単ではありません。
例:
(string-upcase "Straße") ⇒ "STRASSE"
(string-downcase "Straße") ⇒ "straße"
(string-upcase "ΧΑΟΣ") ⇒ "ΧΑΟΣ"
(string-downcase "ΧΑΟΣ") ⇒ "χαος"
(string-downcase "ΧΑΟΣΣ") ⇒ "χαοσς"
(string-downcase "ΧΑΟΣ Σ") ⇒ "χαος σ"
(string-upcase "χαος") ⇒ "ΧΑΟΣ"
(string-upcase "χαοσ") ⇒ "ΧΑΟΣ"
正しい変換を知る前に言語を知る必要があるため、静的テーブルでは十分ではありません。
たとえば、トルコ語i
ではİ
(U+0130) に移動する必要がありますが、他の言語ではI
(U+0049) に移動する必要があります。そして、i
同じ文字 U+0069 です。
ボーナス ポイントは獲得できませんが、7 ビット ASCII の場合は次のようになります。
char toupper(char c)
{
if ((c < 'a') || (c > 'z')) { return c; }
else { return c & 0xdf; }
}
Pythonで..
touppe_map = { massive dictionary to handle all cases in all languages }
def to_upper( c ):
return toupper_map.get( c, c )
または、それを「間違った方法」でやりたい場合
def to_upper( c ):
for k,v in toupper_map.items():
if k == c: return v
return c
ヘブライ語、アラビア語、グルジア語など、大文字 (大文字) を持たない言語については、さらにボーナス ポイントを提案させてください。:-)