Множественные формы числительных в Java
- Информация о материале
- Категория: Различные программы
- Опубликовано: 25.07.2012, 08:04
- Автор: DukeSS
- Просмотров: 3997
Возникла задача сделать многоязычное приложение на Java с выводом чисел и указанием того, что, собственно, выводится, например: 2 кирпича, 10 лет, 5 подушек и т.д. Известные решения (gettext, ChoiceFormat) меня не воодушевили, так как в одном случае надо порождать кучу файлов (по числу языков) и цеплять объёмную библиотеку, а во втором - некорректно обрабатывается русский язык. Решение было принято в пользу создания своего велосипеда и написании небольшого класса, который осуществляет выбор формы существительного при числительном в зависимости от языка и значения числительного.
Информация для "мяса" класса была взята отсюда: http://translate.sourceforge.net/wiki/l10n/pluralforms. Использовать, правда, её с ходу не получилось, так как она содержит некоторые ошибки в синтаксисе, впрочем, не фатальные.
Использование класса осуществляется следующим образом: при создании объекта вызывается конструктор, который либо сам пытается выяснить текущую локаль, либо ему её указывают принудительно. Далее, в нём производится сопоставление кода локали ISO и внутреннего "кода языка". Собственно говоря, это самая долгая операция, поэтому лучше её делать как можно реже. После этого можно вызывать метод convert(int value, "текст1|текст2|..."); на вход которого подаётся число и несколько форм существительного, которые представляют собой одну строку и разделяются вертикальной чертой.
// Data about plural forms get here: // http://translate.sourceforge.net/wiki/l10n/pluralforms import java.util.Locale; public class i10n_pluralforms { private int lang_id = 0; private int nplurals = 0; private String language = ""; public i10n_pluralforms (Locale locale){ language = locale.getLanguage(); lang_id = languageToIntId(language); return; } public i10n_pluralforms (){ Locale locale = Locale.getDefault(); language = locale.getLanguage(); lang_id = languageToIntId(language); return; } private int languageToIntId(String language) { if (language.compareToIgnoreCase("ach") == 0){lang_id = 1;} else if (language.compareToIgnoreCase("af") == 0){lang_id = 2;} else if (language.compareToIgnoreCase("ak") == 0){lang_id = 3;} else if (language.compareToIgnoreCase("sq") == 0){lang_id = 4;} else if (language.compareToIgnoreCase("am") == 0){lang_id = 5;} else if (language.compareToIgnoreCase("ar") == 0){lang_id = 6;} else if (language.compareToIgnoreCase("an") == 0){lang_id = 7;} else if (language.compareToIgnoreCase("es_AR") == 0){lang_id = 8;} else if (language.compareToIgnoreCase("hy") == 0){lang_id = 9;} else if (language.compareToIgnoreCase("ast") == 0){lang_id = 10;} else if (language.compareToIgnoreCase("ay") == 0){lang_id = 11;} else if (language.compareToIgnoreCase("az") == 0){lang_id = 12;} else if (language.compareToIgnoreCase("eu") == 0){lang_id = 13;} else if (language.compareToIgnoreCase("be") == 0){lang_id = 14;} else if (language.compareToIgnoreCase("bn") == 0){lang_id = 15;} else if (language.compareToIgnoreCase("bs") == 0){lang_id = 16;} else if (language.compareToIgnoreCase("pt_BR") == 0){lang_id = 17;} else if (language.compareToIgnoreCase("br") == 0){lang_id = 18;} else if (language.compareToIgnoreCase("bg") == 0){lang_id = 19;} else if (language.compareToIgnoreCase("ca") == 0){lang_id = 20;} else if (language.compareToIgnoreCase("cgg") == 0){lang_id = 21;} else if (language.compareToIgnoreCase("zh") == 0){lang_id = 22;} else if (language.compareToIgnoreCase("kw") == 0){lang_id = 23;} else if (language.compareToIgnoreCase("hr") == 0){lang_id = 24;} else if (language.compareToIgnoreCase("cs") == 0){lang_id = 25;} else if (language.compareToIgnoreCase("da") == 0){lang_id = 26;} else if (language.compareToIgnoreCase("nl") == 0){lang_id = 27;} else if (language.compareToIgnoreCase("dz") == 0){lang_id = 28;} else if (language.compareToIgnoreCase("en") == 0){lang_id = 29;} else if (language.compareToIgnoreCase("eo") == 0){lang_id = 30;} else if (language.compareToIgnoreCase("et") == 0){lang_id = 31;} else if (language.compareToIgnoreCase("fo") == 0){lang_id = 32;} else if (language.compareToIgnoreCase("fil") == 0){lang_id = 33;} else if (language.compareToIgnoreCase("fi") == 0){lang_id = 34;} else if (language.compareToIgnoreCase("fr") == 0){lang_id = 35;} else if (language.compareToIgnoreCase("fy") == 0){lang_id = 36;} else if (language.compareToIgnoreCase("fur") == 0){lang_id = 37;} else if (language.compareToIgnoreCase("ff") == 0){lang_id = 38;} else if (language.compareToIgnoreCase("gl") == 0){lang_id = 39;} else if (language.compareToIgnoreCase("ka") == 0){lang_id = 40;} else if (language.compareToIgnoreCase("de") == 0){lang_id = 41;} else if (language.compareToIgnoreCase("el") == 0){lang_id = 42;} else if (language.compareToIgnoreCase("gu") == 0){lang_id = 43;} else if (language.compareToIgnoreCase("gun") == 0){lang_id = 44;} else if (language.compareToIgnoreCase("ha") == 0){lang_id = 45;} else if (language.compareToIgnoreCase("he") == 0){lang_id = 46;} else if (language.compareToIgnoreCase("hi") == 0){lang_id = 47;} else if (language.compareToIgnoreCase("hu") == 0){lang_id = 48;} else if (language.compareToIgnoreCase("is") == 0){lang_id = 49;} else if (language.compareToIgnoreCase("id") == 0){lang_id = 50;} else if (language.compareToIgnoreCase("ia") == 0){lang_id = 51;} else if (language.compareToIgnoreCase("ga") == 0){lang_id = 52;} else if (language.compareToIgnoreCase("it") == 0){lang_id = 53;} else if (language.compareToIgnoreCase("ja") == 0){lang_id = 54;} else if (language.compareToIgnoreCase("jv") == 0){lang_id = 55;} else if (language.compareToIgnoreCase("kn") == 0){lang_id = 56;} else if (language.compareToIgnoreCase("csb") == 0){lang_id = 57;} else if (language.compareToIgnoreCase("kk") == 0){lang_id = 58;} else if (language.compareToIgnoreCase("km") == 0){lang_id = 59;} else if (language.compareToIgnoreCase("ko") == 0){lang_id = 60;} else if (language.compareToIgnoreCase("ku") == 0){lang_id = 61;} else if (language.compareToIgnoreCase("ky") == 0){lang_id = 62;} else if (language.compareToIgnoreCase("lo") == 0){lang_id = 63;} else if (language.compareToIgnoreCase("lv") == 0){lang_id = 64;} else if (language.compareToIgnoreCase("lb") == 0){lang_id = 65;} else if (language.compareToIgnoreCase("ln") == 0){lang_id = 66;} else if (language.compareToIgnoreCase("lt") == 0){lang_id = 67;} else if (language.compareToIgnoreCase("jbo") == 0){lang_id = 68;} else if (language.compareToIgnoreCase("mk") == 0){lang_id = 69;} else if (language.compareToIgnoreCase("mai") == 0){lang_id = 70;} else if (language.compareToIgnoreCase("mg") == 0){lang_id = 71;} else if (language.compareToIgnoreCase("ms") == 0){lang_id = 72;} else if (language.compareToIgnoreCase("ml") == 0){lang_id = 73;} else if (language.compareToIgnoreCase("mt") == 0){lang_id = 74;} else if (language.compareToIgnoreCase("mnk") == 0){lang_id = 75;} else if (language.compareToIgnoreCase("mi") == 0){lang_id = 76;} else if (language.compareToIgnoreCase("arn") == 0){lang_id = 77;} else if (language.compareToIgnoreCase("mr") == 0){lang_id = 78;} else if (language.compareToIgnoreCase("mfe") == 0){lang_id = 79;} else if (language.compareToIgnoreCase("mn") == 0){lang_id = 80;} else if (language.compareToIgnoreCase("nah") == 0){lang_id = 81;} else if (language.compareToIgnoreCase("nap") == 0){lang_id = 82;} else if (language.compareToIgnoreCase("ne") == 0){lang_id = 83;} else if (language.compareToIgnoreCase("se") == 0){lang_id = 84;} else if (language.compareToIgnoreCase("nso") == 0){lang_id = 85;} else if (language.compareToIgnoreCase("no") == 0){lang_id = 86;} else if (language.compareToIgnoreCase("nb") == 0){lang_id = 87;} else if (language.compareToIgnoreCase("nn") == 0){lang_id = 88;} else if (language.compareToIgnoreCase("oc") == 0){lang_id = 89;} else if (language.compareToIgnoreCase("or") == 0){lang_id = 90;} else if (language.compareToIgnoreCase("pap") == 0){lang_id = 91;} else if (language.compareToIgnoreCase("ps") == 0){lang_id = 92;} else if (language.compareToIgnoreCase("fa") == 0){lang_id = 93;} else if (language.compareToIgnoreCase("pms") == 0){lang_id = 94;} else if (language.compareToIgnoreCase("pl") == 0){lang_id = 95;} else if (language.compareToIgnoreCase("pt") == 0){lang_id = 96;} else if (language.compareToIgnoreCase("pa") == 0){lang_id = 97;} else if (language.compareToIgnoreCase("ro") == 0){lang_id = 98;} else if (language.compareToIgnoreCase("rm") == 0){lang_id = 99;} else if (language.compareToIgnoreCase("ru") == 0){lang_id = 100;} else if (language.compareToIgnoreCase("sco") == 0){lang_id = 101;} else if (language.compareToIgnoreCase("gd") == 0){lang_id = 102;} else if (language.compareToIgnoreCase("sr") == 0){lang_id = 103;} else if (language.compareToIgnoreCase("si") == 0){lang_id = 104;} else if (language.compareToIgnoreCase("sk") == 0){lang_id = 105;} else if (language.compareToIgnoreCase("sl") == 0){lang_id = 106;} else if (language.compareToIgnoreCase("so") == 0){lang_id = 107;} else if (language.compareToIgnoreCase("son") == 0){lang_id = 108;} else if (language.compareToIgnoreCase("es") == 0){lang_id = 109;} else if (language.compareToIgnoreCase("su") == 0){lang_id = 110;} else if (language.compareToIgnoreCase("sw") == 0){lang_id = 111;} else if (language.compareToIgnoreCase("sv") == 0){lang_id = 112;} else if (language.compareToIgnoreCase("tg") == 0){lang_id = 113;} else if (language.compareToIgnoreCase("ta") == 0){lang_id = 114;} else if (language.compareToIgnoreCase("tt") == 0){lang_id = 115;} else if (language.compareToIgnoreCase("te") == 0){lang_id = 116;} else if (language.compareToIgnoreCase("th") == 0){lang_id = 117;} else if (language.compareToIgnoreCase("bo") == 0){lang_id = 118;} else if (language.compareToIgnoreCase("ti") == 0){lang_id = 119;} else if (language.compareToIgnoreCase("tr") == 0){lang_id = 120;} else if (language.compareToIgnoreCase("tk") == 0){lang_id = 121;} else if (language.compareToIgnoreCase("uk") == 0){lang_id = 122;} else if (language.compareToIgnoreCase("ur") == 0){lang_id = 123;} else if (language.compareToIgnoreCase("ug") == 0){lang_id = 124;} else if (language.compareToIgnoreCase("uz") == 0){lang_id = 125;} else if (language.compareToIgnoreCase("vi") == 0){lang_id = 126;} else if (language.compareToIgnoreCase("wa") == 0){lang_id = 127;} else if (language.compareToIgnoreCase("cy") == 0){lang_id = 128;} else if (language.compareToIgnoreCase("wo") == 0){lang_id = 129;} else if (language.compareToIgnoreCase("sah") == 0){lang_id = 130;} else if (language.compareToIgnoreCase("yo") == 0){lang_id = 131;} else lang_id = 0; return lang_id; } public String convert (int integer, String pluralforms){ int plural = 0; int n = Math.abs(integer); switch (lang_id) { case 1: nplurals=2; plural=(n > 1?1:0); break; case 2: nplurals=2; plural=(n == 1?0:1); break; case 3: nplurals=2; plural=(n > 1?1:0); break; case 4: nplurals=2; plural=(n == 1?0:1); break; case 5: nplurals=2; plural=(n > 1?1:0); break; case 6: nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5); break; case 7: nplurals=2; plural=(n == 1?0:1); break; case 8: nplurals=2; plural=(n == 1?0:1); break; case 9: nplurals=2; plural=(n == 1?0:1); break; case 10: nplurals=2; plural=(n == 1?0:1); break; case 11: nplurals=1; plural=0; break; case 12: nplurals=2; plural=(n == 1?0:1); break; case 13: nplurals=2; plural=(n == 1?0:1); break; case 14: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); break; case 15: nplurals=2; plural=(n == 1?0:1); break; case 16: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); break; case 17: nplurals=2; plural=(n == 1?0:1); break; case 18: nplurals=2; plural=(n > 1?1:0); break; case 19: nplurals=2; plural=(n == 1?0:1); break; case 20: nplurals=2; plural=(n == 1?0:1); break; case 21: nplurals=1; plural=0; break; case 22: nplurals=1; plural=0; break; case 23: nplurals=4; plural= ((n==1) ? 0 : (n==2) ? 1 : (n == 3) ? 2 : 3); break; case 24: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); break; case 25: nplurals=3; plural=((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2); break; case 26: nplurals=2; plural=(n == 1?0:1); break; case 27: nplurals=2; plural=(n == 1?0:1); break; case 28: nplurals=1; plural=0; break; case 29: nplurals=2; plural=(n == 1?0:1); break; case 30: nplurals=2; plural=(n == 1?0:1); break; case 31: nplurals=2; plural=(n == 1?0:1); break; case 32: nplurals=2; plural=(n == 1?0:1); break; case 33: nplurals=2; plural=(n > 1?1:0); break; case 34: nplurals=2; plural=(n == 1?0:1); break; case 35: nplurals=2; plural=(n > 1?1:0); break; case 36: nplurals=2; plural=(n == 1?0:1); break; case 37: nplurals=2; plural=(n == 1?0:1); break; case 38: nplurals=2; plural=(n == 1?0:1); break; case 39: nplurals=2; plural=(n == 1?0:1); break; case 40: nplurals=1; plural=0; break; case 41: nplurals=2; plural=(n == 1?0:1); break; case 42: nplurals=2; plural=(n == 1?0:1); break; case 43: nplurals=2; plural=(n == 1?0:1); break; case 44: nplurals=2; plural =(n > 1?1:0); break; case 45: nplurals=2; plural=(n == 1?0:1); break; case 46: nplurals=2; plural=(n == 1?0:1); break; case 47: nplurals=2; plural=(n == 1?0:1); break; case 48: nplurals=2; plural=(n == 1?0:1); break; case 49: nplurals=2; plural=((n%10!=1 || n%100==11)?1:0); break; case 50: nplurals=1; plural=0; break; case 51: nplurals=2; plural=(n == 1?0:1); break; case 52: nplurals=5; plural=(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4); break; case 53: nplurals=2; plural=(n == 1?0:1); break; case 54: nplurals=1; plural=0; break; case 55: nplurals=2; plural=(n == 0?0:1); break; case 56: nplurals=2; plural=(n == 1?0:1); break; case 57: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); break; case 58: nplurals=1; plural=0; break; case 59: nplurals=1; plural=0; break; case 60: nplurals=1; plural=0; break; case 61: nplurals=2; plural=(n == 1?0:1); break; case 62: nplurals=1; plural=0; break; case 63: nplurals=1; plural=0; break; case 64: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2); break; case 65: nplurals=2; plural=(n == 1?0:1); break; case 66: nplurals=2; plural=(n > 1?1:0); break; case 67: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2); break; case 68: nplurals=1; plural=0; break; case 69: nplurals=2; plural= (n==1 || n%10==1 ? 0 : 1); break; case 70: nplurals=2; plural=(n == 1?0:1); break; case 71: nplurals=2; plural=(n > 1?1:0); break; case 72: nplurals=1; plural=0; break; case 73: nplurals=2; plural=(n == 1?0:1); break; case 74: nplurals=4; plural=(n==1 ? 0 : n==0 || ( n%100>1 && n%100<11) ? 1 : (n%100>10 && n%100<20 ) ? 2 : 3); break; case 75: nplurals=3; plural=(n==0 ? 0 : n==1 ? 1 : 2); break; case 76: nplurals=2; plural=(n > 1?1:0); break; case 77: nplurals=2; plural=(n > 1?1:0); break; case 78: nplurals=2; plural=(n == 1?0:1); break; case 79: nplurals=2; plural=(n > 1?1:0); break; case 80: nplurals=2; plural=(n == 1?0:1); break; case 81: nplurals=2; plural=(n == 1?0:1); break; case 82: nplurals=2; plural=(n == 1?0:1); break; case 83: nplurals=2; plural=(n == 1?0:1); break; case 84: nplurals=2; plural=(n == 1?0:1); break; case 85: nplurals=2; plural=(n == 1?0:1); break; case 86: nplurals=2; plural=(n == 1?0:1); break; case 87: nplurals=2; plural=(n == 1?0:1); break; case 88: nplurals=2; plural=(n == 1?0:1); break; case 89: nplurals=2; plural=(n > 1?1:0); break; case 90: nplurals=2; plural=(n == 1?0:1); break; case 91: nplurals=2; plural=(n == 1?0:1); break; case 92: nplurals=2; plural=(n == 1?0:1); break; case 93: nplurals=1; plural=0; break; case 94: nplurals=2; plural=(n == 1?0:1); break; case 95: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); break; case 96: nplurals=2; plural=(n == 1?0:1); break; case 97: nplurals=2; plural=(n == 1?0:1); break; case 98: nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2); break; case 99: nplurals=2; plural=(n == 1?0:1); break; case 100: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); break; case 101: nplurals=2; plural=(n == 1?0:1); break; case 102: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3; break; case 103: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); break; case 104: nplurals=2; plural=(n == 1?0:1); break; case 105: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2; break; case 106: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n%100==4 ? 3 : 0); break; case 107: nplurals=2; plural=(n == 1?0:1); break; case 108: nplurals=2; plural=(n == 1?0:1); break; case 109: nplurals=2; plural=(n == 1?0:1); break; case 110: nplurals=1; plural=0; break; case 111: nplurals=2; plural=(n == 1?0:1); break; case 112: nplurals=2; plural=(n == 1?0:1); break; case 113: nplurals=2; plural=(n > 1?1:0); break; case 114: nplurals=2; plural=(n == 1?0:1); break; case 115: nplurals=1; plural=0; break; case 116: nplurals=2; plural=(n == 1?0:1); break; case 117: nplurals=1; plural=0; break; case 118: nplurals=1; plural=0; break; case 119: nplurals=2; plural=(n > 1?1:0); break; case 120: nplurals=2; plural=(n > 1?1:0); break; case 121: nplurals=2; plural=(n == 1?0:1); break; case 122: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); break; case 123: nplurals=2; plural=(n == 1?0:1); break; case 124: nplurals=1; plural=0;; break; case 125: nplurals=2; plural=(n > 1?1:0); break; case 126: nplurals=1; plural=0; break; case 127: nplurals=2; plural=(n > 1?1:0); break; case 128: nplurals=4; plural= ((n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3); break; case 129: nplurals=1; plural=0; break; case 130: nplurals=1; plural=0; break; case 131: nplurals=2; plural=(n == 1?0:1); break; } if(nplurals == 0) return "i10n_pluralforms: Oops! Unknown language " + language; String parsedString[] = pluralforms.split("\\|"); if(parsedString.length < nplurals) return "i10n_pluralforms: Oops! Not enough plural forms in \"" + pluralforms + "\" for language " + language; return parsedString[plural]; } }