Локализация 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}". Это звучит слабо, но удивительно, что в последний раз, когда я проверял, в большинстве случаев исследования удобства использования фактически не способствовали многословному представлению естественного языка.