代码之家  ›  专栏  ›  技术社区  ›  Colin Pickard

重新实现toupper()

  •  3
  • Colin Pickard  · 技术社区  · 16 年前

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

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

    6 回复  |  直到 11 年前
        1
  •  8
  •   Aaron Digulla    16 年前
    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图表中找到 unicode.org 包含字符/代码点的名称。此字符串将包含大写字符的“small”(小)(注意空格或可能与“smaller”等匹配)。现在,您可以搜索类似的名称,用“小”替换为“大写”。如果你找到了,你就找到了标题版本。

        2
  •  7
  •   Tomalak    16 年前

    我不认为这样可以在一次发布中处理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 "χαοσ")      ⇒ "ΧΑΟΣ"
    
        3
  •  5
  •   Douglas Leeder    16 年前

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

    例如土耳其语 i 需要去 Ä° (U+0130),而在任何其他语言中,需要转到 I (u+0049)。以及 是同一个字符U+0069。

        4
  •  1
  •   James Eichele Bernard Igiri    16 年前

    我不会赢得加分,但这里是7位ASCII:

    char toupper(char c)
    {
        if ((c < 'a') || (c > 'z')) { return c; }
        else { return c & 0xdf; }
    }
        5
  •  0
  •   hasen    16 年前

    用蟒蛇…

    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
    
        6
  •  0
  •   Boris Gorelik    16 年前

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