ASP.NET本地化(单数和复数)

alen0pnh  于 2022-11-19  发布在  .NET
关注(0)|答案(8)|浏览(237)

我可以用ASP.NET资源/本地化翻译字符串,使其以一种简单的方式依赖于一个或另一个(英语语法)吗?就像我在翻译中传递数字1,它返回“You have one car”,或者传递0,2和更高的数字,返回“You have %n汽车”?
或者我被迫在我的观点中有逻辑,看看它是单数还是复数?

2o7dmzc5

2o7dmzc51#

JasonTrue写道:
据我所知,没有一种语言需要比单复数更复杂的东西
这样的语言确实存在,例如在我的母语波兰语中,有三种形式:1、2-4、0和大于4的数字。当你达到20时,21、22- 2 - 4和25+的形式再次不同(与数字0-9的语法形式相同)。是的,“你有0件东西”听起来很别扭,因为你不太可能在真实的生活中看到它的使用。

作为一名本地化Maven,以下是我的建议:

如有可能,请使用将数字放在末尾的表格:

a: Number of cars: %d

这意味着名词“car”的形式不依赖于数字,0和其他数字一样自然。
如果上面的方法不能被接受,至少要把一个完整的句子变成一个可翻译的资源。

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

绝不要将这些单元拆分为更小的片段,如

d: You have
e: car(s)

(Then在其他地方有不可本地化的资源,例如%s%d%s
不同之处在于,虽然我不能直接翻译(c),但由于名词的形式会改变,我 * 能看到问题 *,我能在翻译中把句子变成形式(a)。
另一方面,当我面对(d)和(e)片段时,没有办法确保最终的句子符合语法。使用片段保证了在某些语言中翻译将是从语法上笨拙到完全断裂的任何事情。
这一点不仅适用于数词,也适用于其他语言。例如,像%s was deleted这样的片段也是不可翻译的,因为动词的形式取决于名词的性别,而这在这里是不适用的。我能为波兰语做的最好的翻译就是相当于Deleted: %s。但是我只能在可翻译资源中包含%s占位符的情况下这样做。如果我所知道的只是“被删除了,”而没有关于所指名词的线索,我只能大声咒骂来吓我的狗,最后我还得产生垃圾语法。

bd1hkmkf

bd1hkmkf2#

我一直在开发一个库来帮助一个应用程序的国际化。它被称为**SmartFormat**,是GitHub上的开源库。
它包含许多语言的“语法数字”规则,这些规则根据区域设置确定正确的单/复数形式。当翻译包含依赖于数量的单词的短语时,您指定多种形式,格式化程序将根据这些规则选择正确的形式。
例如:

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

它的语法与String.Format(...)非常相似,但是它有很多很棒的特性,可以很容易地创建自然且语法正确的消息。
它还处理可能的性别特定格式、列表等。

xesrikrc

xesrikrc3#

穆德福拉迪写道:
这一点不仅适用于数字,也适用于其他语言。例如,像“%s was deleted”这样的片段也是不可翻译的,因为动词的形式取决于名词的性别,而这一点在这里是不适用的。我能为波兰语做的最好的翻译就是相当于“Deleted:%s”,但我只能这样做,只要%s占位符包括在可翻译的资源。如果我所有的是“被删除”没有线索的所指名词,我只能吓我的狗大声咒骂,最后我仍然要产生垃圾语法。
我想在这里指出的一点是,永远不要将名词作为参数。许多欧洲语言根据其性别来修饰名词,在德语中,无论它是主语、宾语还是间接宾语。只要使用单独的消息即可。不要使用“%s已删除",而要为每种类型使用单独的翻译字符串:“交易已删除”、“用户已删除”等。
这样,每个字符串都可以正确翻译。
处理不同语言中复数形式的解决方案可在此处找到:http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html
虽然你不能在商业应用中使用上述软件(GPL中有介绍),您可以使用相同的概念。它们的复数形式表达式与. NET中的lambda表达式非常吻合。有数量有限的复数形式表达式,但涵盖了大量语言。您可以将特定语言Map到lambda表达式,该表达式根据该语言计算使用哪种复数形式。然后,请在. NETresx文件中查找相应的复数形式。

lkaoscv7

lkaoscv74#

AFAIK,框架中没有内置任何东西来做这件事。
下面是该问题的一个通用解决方案的示例:
http://dotnetperls.com/plural

mrfwxfqh

mrfwxfqh5#

没有内置任何内容,我们最终编写了如下代码:另一种解决方案可以是:
在资源文件字符串中使用占位符(如{CAR})为“car”的单数和复数单词维护单独的资源条目:汽车_SINGULAR汽车
CAR_多辆汽车
使用此逻辑开发类:

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";
}
gab6jxml

gab6jxml6#

这在.NET中仍然是不可能的。但是这是一个众所周知的问题,并且已经被gettext解决了。它对许多技术都有本机支持,甚至包括C#支持。但是现在看起来.NET中有了现代的重新实现:https://github.com/VitaliiTsilnyk/NGettext

k2arahey

k2arahey8#

逻辑不一定在您的视图中,但它肯定不在资源模型DotNet框架中。您的情况非常简单,您可能只需为单数和复数创建一个简单的格式字符串。“You have 1 car."/“You have {0}汽车.”然后您需要编写一个方法来区分复数和单数。
也有一些语言在单数和复数之间没有区别,但这只需要在资源字符串中有一点重复。(编辑以添加:在许多语言中,性别,有时结尾会根据单位的数量而变化,但只要你区分单数和复数句子,而不仅仅是单词,这应该是好的)。
微软基本上放弃了语义智能的本地化,因为即使是像复数这样的东西也很难推广到30多种语言。这就是为什么在大多数被翻译成多种语言的应用程序中,你会看到如此无聊的数字量表示,沿着“汽车:{0}"。这听起来很蹩脚,但令人惊讶的是,上次我检查时,可用性研究在大多数情况下实际上并不支持冗长的自然语言表示。

相关问题