3

如果 ToUpper() 不存在,你将如何编写它?i18n 和 L10n 的奖励积分

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

4

6 回答 6

8
  1. 我下载了 Unicode 表
  2. 我将表导入数据库
  3. 我写了一个方法upper()。

这是一个示例实现;)

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”。如果你找到它,你就找到了大写版本。

于 2008-12-02T14:41:54.827 回答
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 "χαοσ")      ⇒ "ΧΑΟΣ"
于 2008-12-02T13:49:51.967 回答
5

没有静态表是足够的,因为您需要先了解语言,然后才能知道正确的转换。

例如,在土耳其语i中需要转到İ(U+0130) 而在任何其他语言中需要转到I(U+0049) 。和iU+0069 是同一个字符。

于 2008-12-02T14:25:35.267 回答
1

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

char toupper(char c)
{
    if ((c < 'a') || (c > 'z')) { return c; }
    else { return c & 0xdf; }
}
于 2008-12-02T13:50:06.867 回答
0

在蟒蛇..

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
于 2008-12-02T14:02:00.820 回答
0

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

于 2008-12-02T14:16:21.883 回答