Локализация ASP.NET с сингулярным и множественным числом

Могу ли я с ASP.NET ресурсами/Локализацией переводить строки, чтобы зависеть от той или иной (английской грамматики) простым способом, например, я передаю номер 1 в своем переводе, он возвращает "У вас есть один автомобиль" или с 0, 2 и выше, "У вас есть% n автомобилей"?

Или я вынужден иметь логику на мой взгляд, чтобы увидеть, является ли она единственной или множественной?

Ответы

Ответ 1

JasonTrue писал (а):

To the best of my knowledge, there isn't a language 
that requires something more complicated than singular/plural

Такие языки существуют. На моем родном польском языке, например, существует три формы: для 1, для 2-4 и для нуля и числа больше 4. Затем, после достижения 20, формы для 21, 22-24 и 25+ снова различаются ( те же грамматические формы, что и для цифр 0-9). И да, "у вас есть 0 вещей" звучит неудобно, потому что вы вряд ли увидите, что это используется в реальной жизни.

Как специалист по локализации, вот что я бы рекомендовал:

Если возможно, используйте формы, которые положили цифру в конце:

a: Number of cars: %d

Это означает, что форма существительного "автомобиль" не зависит от цифры, а 0 является таким же естественным, как любое другое число.

Если вышеуказанное неприемлемо, по крайней мере всегда делайте полное предложение переводимым ресурсом. То есть, используйте

b: You have 1 car.    
c: You have %d cars.

Но никогда не разбивает такие единицы на более мелкие фрагменты, такие как

d: You have
e: car(s)

(Тогда в другом месте у вас есть не локализуемый ресурс sch как "% s% d% s" )

Разница в том, что, хотя я не могу перевести (c) напрямую, поскольку форма существительного изменится, я вижу проблему, и я могу изменить предложение на форму (a) в переводе.

С другой стороны, когда я сталкиваюсь с фрагментами (d) и (e), нет способа убедиться, что результирующее предложение будет грамматическим. Опять же: использование фрагментов гарантирует, что на некоторых языках перевод будет чем-либо от грамматически неудобного до полного нарушения.

Это применяется по всем направлениям, а не только к цифрам. Например, фрагмент, такой как "% s был удален", также непереводимый, так как форма глагола будет зависеть от пола существительного, который здесь недоступен. Лучшее, что я могу сделать для польского, - это эквивалент "Удалено:% s", но я могу это сделать только до тех пор, пока местозаместитель% s включен в переводимый ресурс. Если все, что у меня есть, "было удалено", без подсказки к ссылочному существительному, я могу только напугать свою собаку, проклиная вслух, и в конце мне все равно придется производить мусорную грамматику.

Ответ 2

Я работаю над библиотекой, чтобы помочь в интернационализации приложения. Он называется SmartFormat и является открытым исходным кодом на GitHub.

Он содержит правила "грамматического числа" для многих языков, которые определяют правильную единственную/множественную форму на основе языкового стандарта. При переводе фразы, содержащей слова, зависящие от количества, вы указываете несколько форм, и форматер выбирает правильную форму на основе этих правил.

Например:

var message = "There {0:is:are} {0} {0:item:items} remaining.";
var output = Smart.Format(culture, message, items.Count);

Он имеет очень похожий синтаксис для String.Format(...), но имеет множество отличных функций, которые облегчают создание естественных и грамматически правильных сообщений.

В нем также рассматриваются возможные гендерные особенности, списки и многое другое.

Ответ 3

moodforaday писал (а):

Это применяется по всем направлениям, а не только к цифрам. Например, фрагмент, такой как "% s был удален", также непереводимый, так как форма глагола будет зависеть от пола существительного, который здесь недоступен. Лучшее, что я могу сделать для польского, - это эквивалент "Удалено:% s", но я могу это сделать только до тех пор, пока местозаместитель% s включен в переводимый ресурс. Если все, что у меня есть, "было удалено", без подсказки к ссылочному существительному, я могу только напугать свою собаку, проклиная вслух, и в конце мне все равно придется производить мусорную грамматику.

Точка, которую я хотел бы сделать здесь, никогда не включает существительное в качестве параметра. Многие европейские языки изменяют существительное на основе его пола, а в случае с немцами - предмет, объект или косвенный объект. Просто используйте отдельные сообщения. Вместо "% s был удален", используйте отдельную строку перевода для каждого типа: "Сделка была удалена". "Пользователь удален". и др.

Таким образом, каждая строка может быть переведена правильно.

Решение для обработки множественных форм на разных языках можно найти здесь: http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html

Хотя вы не можете использовать вышеуказанное программное обеспечение в коммерческом приложении (оно распространяется под GPL), вы можете использовать те же концепции. Их выражения множественной формы отлично вписываются в лямбда-выражения в .NET. Существует ограниченное число выражений формы множественного числа, которые охватывают большое количество языков. Вы можете сопоставить определенный язык с выражением лямбда, который вычисляет, какую форму множественного числа использовать на основе языка. Затем найдите соответствующую множественную форму в файле .NET resx.

Ответ 4

AFAIK, нет ничего встроенного в фреймворк, чтобы сделать это.

Здесь приведен пример одного обобщенного решения задачи:

http://dotnetperls.com/plural

Ответ 5

anvilis wrote:

Точка, которую я хотел бы сделать здесь, никогда не включает существительное в качестве параметра. Многие европейские языки изменяют существительное на основе его пола, а в случае с немцами - предмет, объект или косвенный объект. Просто используйте отдельные сообщения. Вместо "% s был удален" используйте отдельную строку перевода для каждого типа: "Сделка удалена". "Пользователь удален". и др.

Мне всегда было любопытно, как правильно сделать что-то подобное выше, но это включает строку, которая не может быть включена как часть перевода, например "% s said:" или "% s wrote:" (который можно увидеть в настоящее время на facebook). В этом случае,% s является, скорее всего, именем пользователя, а глагол зависит от пола пользователя, например.

(извините за то, что написал это как ответ вместо использования комментария - я не могу найти ссылку для комментариев)

Ответ 6

Нет ничего встроенного, мы закончили тем, что кодировали что-то вроде этого: Другим решением может быть:

используйте держатели мест, например {CAR} в строках файла ресурсов Ведение отдельных записей ресурсов для единственных и множественных слов для "автомобиля":   CAR_SINGULAR автомобиль
  Автомобили CAR_PLURAL

Разработайте класс с помощью этой логики:

class MyResource
 {

    private List<string> literals = new List<string>();
    public MyResource() { literals.Add("{CAR}") }
    public static string GetLocalizedString(string key,bool isPlural)
    {
       string val = rm.GetString(key);
       if(isPlural)
       {
          val = ReplaceLiteralWithPlural(val);
       }
       else
       {
          val = ReplaceLiteralWithSingular(val);   
       }     
    }  
}

string ReplaceLiteralWithPlural(string val)
{
   StringBuilder text = new StringBuilder(val)
   foreach(string literal in literals)
   {
      text = text.Replace(literal,GetPluralKey(literal));
   }
}

string GetPluralKey(string literal)
{
  return literal + "_PLURAL";
}

Ответ 7

Логика не обязательно должна быть в вашем представлении, но она, конечно, не в модели ресурсов DotNet. Ваш достаточно простой случай, что вы, вероятно, можете уйти с созданием простой строки форматирования для единственного числа, а другой для множественного числа. "У вас 1 автомобиль"./ "У вас есть {0} машины". Затем вам нужно написать метод, который различает множественный и сингулярный случай.

Насколько мне известно, нет языка, требующего чего-то более сложного, чем единственное/множественное число, но может быть и то, где выражение эквивалента "у вас есть 0 автомобилей" звучит не так. Существует также ряд языков, где нет различия между сингулярным и множественным числом, но для этого требуется небольшое дублирование в строках ресурсов. (изменить для добавления: пол, а иногда и конечные значения изменяются в зависимости от количества единиц на многих языках, но это должно быть хорошо, если вы различаете исключительные и множественные предложения, а не просто слова).

Microsoft в основном отказалась от семантически умной локализации, потому что трудно обобщить даже что-то вроде плюрализации на 30 + языков. Вот почему вы видите такое скучное представление числовых величин в большинстве приложений, которые переведены на многие языки, в соответствии с "Автомобили: {0}". Это звучит слабо, но удивительно, что в последний раз, когда я проверял, в большинстве случаев исследования удобства использования фактически не способствовали многословному представлению естественного языка.