将带占位符的字符串(“{0}”)添加到资源中是个好主意吗

本文关键字:资源 添加 好主意 占位符 字符串 | 更新日期: 2023-09-27 17:57:33

我在资源文件中添加了一个字符串。我的应用程序将进行本地化
但是,在资源中添加带占位符的字符串({0})是个好主意吗
如果某个非技术人员进行本地化会怎样?有没有办法让他们在不知不觉中把事情搞砸?

如果这不是一个好主意,我该怎么办?

下面是一个简单的例子。我将使用WPF资源字典。

示例:

// Resource1.resx
//        Name               |            Value
//---------------------------------------------------------------
// RELATIONSHIP_STATUS_MSG   | {0} is in relationship with {1}. 
//

class Program
{
    static void Main(string[] args)
    {
        string msg = string.Format(Resource1.RELATIONSHIP_STATUS_MSG, 
                                   "Romeo", "Juliot");
        Console.WriteLine(msg);
    }
}

将带占位符的字符串(“{0}”)添加到资源中是个好主意吗

好吧,我认为这是一个好主意,因为这是一种简单快捷的渲染参数化和本地化字符串的方法。

顺便说一句,正如你在问题中所说,非技术人员可能会破坏你的本地化字符串,因为他们不理解什么是"{0}"。我有两种解决这个问题的"方法"

  1. 请注意,维护本地化字符串的非技术人员不必关心括号中的文本。

  2. 使用命名占位符:"{some identifier}",只使用someTextResource.Replace("{some-identifier}", someTextVar)

关于第二个,您可以实现一些方法来接受替换关系的IDictionary<TKey, TValue>实例,其中键是要替换的标识符,并对要放置的文本进行赋值以替换标识符。

取决于

有时您别无选择,只能使用占位符,例如用于动态数据。在这种情况下,使用占位符,尤其是带编号的占位符({0},{1},…)不仅是一个好主意,而且从国际化的角度来看也是最可接受的想法。它允许在翻译过程中对句子进行重新排序,这肯定是你想要支持的
至于非技术人员。。。好吧,如果你使用的是专业的软件翻译供应商,他们不会有任何问题,他们只是习惯于翻译这样的字符串。若你们只想任命一个通用的翻译人员,那个可能会带来问题。但在这种情况下,我必须警告您,技术翻译是特定的:/strong>:翻译人员至少应该遵守通用软件术语表。

好的,现在开始为什么它依赖。基本上,用字符串格式化字符串。Format()实际上是串联的。正如我所说,如果你有动态数据,你别无选择。但是,如果您的数据是静态的,并且只有很少的组合,那么在任何情况下都不应该使用占位符(也不应该使用带有串联(+)运算符的简单字符串串联,也不应该更复杂地使用StringBuilder)。对于静态数据,只需创建所需数量的字符串即可
真正的原因是,许多语言需要根据上下文不同的翻译形式。例如,在我的母语(波兰语)中,我们对阴性名词和阳性名词使用不同的形式
这不仅仅是理论上的问题:4年前,当我在本地化工作时,我们不得不本地化新的主要反病毒软件。问题是,一些程序员优化了资源,所以我们有一个类似的消息:

The {0} is inactive. To activate {0} click...

占位符被替换的是函数或程序名称。在波兰语中函数是阴性的,按程序是阳性的。更糟糕的是,我们的语言学家想要添加单词"program"answers"funkcja",这取决于什么实际上是不活跃的
显然,我们(本地化软件工程师)无法在不接触代码的情况下解决问题(我们不被允许这样做,但这是另一回事…)

总结:
如果你真的必须使用占位符。磁盘空间很便宜。避免串联(因为这不允许对翻译的句子进行重新排序)
不要太担心翻译,但要记住给他们上下文(可能还有说明)。对他们来说,了解字符串将在哪里显示以及哪些值是可能的非常重要。

如果这样做,请确保记录非技术翻译人员的行为。否则你应该没事的。

使用自动化测试来验证翻译供应商返回的资源文件的完整性。理想情况下,为供应商提供在翻译期间执行此操作的工具,以便尽早发现缺陷。

即使您为非技术翻译人员提供了一份文档,他们仍有可能(在不知情的情况下)利用它,但如果您自己处理这种情况,这就不是问题了。我宁愿连接字符串。

我认为这是推荐的方法。GNUGetText的指导方针建议这样做。

正如Erno所评论的,请确保翻译人员知道{0}代表什么。

这种方法的一个好处是,您可以控制值的插入位置以及部分值的格式设置。你错过的是价值观的多元化,但那是另一种讨论。

我通常会为这些类型字符串制定一个命名方案,以便它们在代码中脱颖而出。

像Strings.RELATIONSHIP_STATUS_MSG_FORMAT 一样

我喜欢Resharper的命名惯例:__0__is_in_relationship_with__1__

明确了从代码中使用时预期的参数:

string msg = string.Format(Properties.Resources.__0__is_in_relationship_with__1__,
                           "Romeo", 
                           "Juliet");