重新实现ToUpper()

时间:2008-12-02 13:44:00

标签: language-agnostic unicode localization internationalization toupper

如果ToUpper()不存在,你会怎么写? i18n和L10n的奖励积分

由此引发的好奇心:http://thedailywtf.com/Articles/The-Long-Way-toUpper.aspx

6 个答案:

答案 0 :(得分:8)

  1. 我下载了Unicode表格
  2. 我将表格导入数据库
  3. 我写了一个方法upper()。
  4. 以下是一个示例实现;)

    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”的类似名称。如果你找到它,你就找到了自然版本。

答案 1 :(得分:7)

我不认为SO可以在一个帖子中处理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 "χαοσ")      ⇒ "ΧΑΟΣ"

答案 2 :(得分:5)

没有静态表就足够了,因为在知道正确的变换之前需要先了解语言。

e.g。土耳其语i需要转到İ(U + 0130),而其他任何语言都需要转到I(U + 0049)。而i是相同的字符U + 0069。

答案 3 :(得分:1)

我不会赢得奖励积分,但这里是7位ASCII:

char toupper(char c)
{
    if ((c < 'a') || (c > 'z')) { return c; }
    else { return c & 0xdf; }
}

答案 4 :(得分:0)

在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

答案 5 :(得分:0)

让我为希伯来语,阿拉伯语,格鲁吉亚语和其他没有大写(大写)字母的语言建议更多的奖励积分。 : - )