44

我读过 Joel 关于Unicode的文章,我觉得我至少从字符集的角度对国际化有了基本的了解。除了阅读这个问题之外,我还对设计考虑方面的国际化进行了一些自己的研究,但我不禁怀疑还有很多我不知道或不知道的地方不知道问。

我学到的一些东西:

  • 有些语言从右到左而不是从左到右阅读。
  • 日历、日期、时间、货币和数字的显示因语言而异。
  • 设计应该足够灵活以容纳更多文本,因为某些语言比其他语言冗长得多。
  • 当涉及到它们的语义含义时,不要将图标或颜色视为理所当然,因为这可能因文化而异。
  • 地理名称因语言而异。

我在哪里:

  • 我的设计足够灵活,可以容纳更多的文本。
  • 我会自动翻译每个字符串,包括错误消息和帮助对话框。
  • 我还没有到需要显示时间单位、货币或数字的地步,但我很快就会到那里,需要开发一个解决方案。
  • 我正在全面使用 UTF-8 字符集。
  • 我的菜单和应用程序中的各种列表按每种语言的字母顺序排序,以便于阅读。
  • 我有一个标签解析器,它通过过滤掉停用词来提取标签。停用词列表是特定于语言的,可以换掉。

我想了解更多:

  • 我正在开发一个可下载的 PHP Web 应用程序,因此任何有关 PHP 的具体建议将不胜感激。我已经开发了自己的框架,目前对使用其他框架不感兴趣。
  • 我对非西方语言知之甚少。有没有我上面没有提到的需要考虑的具体因素?另外,PHP 的数组排序函数如何处理非西方字符?
  • 您在实践中是否遇到过任何具体的问题?我正在查看 GUI 和应用程序代码本身。
  • 关于使用日期和时间显示的任何具体建议?是否按地区或语言分类?
  • 我见过很多项目和网站让他们的社区为他们的应用程序和内容提供翻译。你推荐这个吗?有什么好的策略来确保你有一个好的翻译?
  • 这个问题基本上是我对国际化的了解程度。什么我不知道我不知道我应该进一步研究?

编辑:我添加了赏金,因为我想从经验中获得更多真实世界的例子。

4

11 回答 11

57

我们的游戏Gemsweeper已被翻译成 8 种不同的语言。在这个过程中我学到了一些东西:

  • 如果给译者一个句子来翻译,请确保他知道每个句子的上下文。否则他可能会提供一种可能的翻译,但不是你想要的那个。Babelfish等工具在不了解上下文的情况下进行翻译,这就是为什么结果通常如此糟糕的原因。只需尝试将任何重要的文本从英语翻译成德语并返回,您就会明白我的意思。

  • 应该翻译的句子不能因为相同的原因分成不同的部分。那是因为您需要维护上下文(请参阅前一点),并且因为某些语言可能在句子的开头或结尾有变量。使用占位符而不是拆分句子。例如,而不是

“这是我们 15 步教程中的一步”

写一些类似的东西:

“这是我们 15 步教程的第 %1 步”

并以编程方式替换占位符。

  • 不要期望翻译者很有趣或有创意。除非您为特定的文本段落命名并支付额外费用,否则他通常没有足够的动力去做。例如,如果您的语言资产中有笑话,请在旁注中告诉翻译人员不要尝试翻译它们,而是将它们排除在外或用更阴沉的句子替换它们。否则翻译者可能会逐字翻译笑话,这通常会导致完全胡说八道。在我们的案例中,我们有一名翻译和一名笑话作者负责最关键的翻译(英语)。

  • 尝试找到一位翻译人员,他的第一语言是他要将您的软件翻译成的语言,而不是相反。否则,他可能会写出可能是正确的文本,但对母语人士来说听起来很奇怪或过时。此外,他应该居住在您翻译目标的国家/地区。例如,来自瑞士的说德语的人不是德语翻译的好选择。

  • 如果可能,请让您的一位了解特定翻译的公共 beta 测试用户验证翻译的资产和完成的软件。我们有一些非常好的和非常差的翻译,这取决于提供它的人。根据我们的一些用户的说法,瑞典语翻译完全是胡言乱语,但已经为时已晚。

  • 请注意,对于每个具有新功能的更新版本,您都必须翻译您的语言资产。这会产生一些严重的开销。

  • 请注意,如果您的软件被翻译,最终用户会期望技术支持会说他们的语言。再一次,Babelfish 很可能不会这样做。

编辑 - 更多点

  • 使本地化之间的切换尽可能容易。在 Gemsweeper 中,我们有一个在不同语言之间切换的热键。它使测试变得更加容易。

  • 如果您要使用异国字体,请确保这些字体包含特殊字符。我们为 Gemsweeper 选择的字体非常适合英文文本,但我们不得不手动添加相当多的字符,这些字符仅存在于德语、法语、葡萄牙语、瑞典语……

  • 不要编写自己的本地化框架。使用像Gettext这样的开源框架可能会好得多。Gettext 支持句子中的变量或复数形式等功能,并且坚如磐石。本地化资源被编译,所以没有人可以篡改它们。另外,您可以使用Poedit之类的工具来翻译您的文件/检查其他人的翻译,并确保所有字符串都已正确翻译并且在您更改底层源代码时仍然是最新的。我已经尝试过自己滚动和使用 Gettext,我不得不说 Gettext 加 PoEdit 非常出色。

编辑 - 更多点

  • 了解不同的文化有不同风格的数字和日期格式。编号方案不仅因文化而异,而且在该文化中也因目的而异。在 EN-US 中,您可以格式化数字“-1234”;'-1,234' 或 (1,234) 取决于数字的用途。了解其他文化也会做同样的事情。

  • 了解您从哪里获得全球化信息。例如,Windows 具有 CurrentCulture、UICulture 和 InvariantCulture 的设置。了解每一个的含义以及它如何与您的系统交互(它们并不像您想象的那么明显)。

  • 如果你要做东亚翻译,真的要做好功课。东亚语言与这里的语言有很多不同。除了同时使用多个字母之外,它们还可以使用不同的布局系统(自上而下)或基于网格。东亚语言中的数字也可能非常不同。在 en-US 中,您只能在有限的条件下更改系统(例如 1 与 1st),除了逗号和句点之外,还有其他数字注意事项。

于 2009-03-13T19:19:51.563 回答
11
  • 我的菜单和应用程序中的各种列表按每种语言的字母顺序排序,以便于阅读。

列表应该排序,菜单不应该。请记住,给定的用户可能希望以一种以上的语言使用您的应用程序,他仍然应该在同一个地方找到任何地方。

与快捷方式相同,如果有的话:不要翻译它们

另外,请记住,国际化和翻译是两个非常不同的事情,分别管理它们。

于 2009-03-13T19:11:20.243 回答
11

当我们处理 Dreamfall 和柯南时代的 i18n/l10n 问题时,我们遇到了一些值得牢记的问题。其中一些是我们解决的,一些是为我们解决的,还有一些是我们解决的。有些我们从未解决...

  • 确保您的所有工具和所有代码都支持您要使用的所有字符集,并在项目过程中仔细检查该假设两次,并再次确认。

  • 确保您使用的字体支持您要使用的所有语言。大多数声称是 unicode 的字体只是 unicode,因为它具有的字符位于正确的代码点。这并不意味着它对所有代码点都有可用的字符。

  • 文本换行不仅在空格处完成,因为某些语言不使用空格来分隔单词(想到中文)。确保您的文本换行例程处理文本时完全没有任何空格。

  • 在简单的情况下正确处理复数是很棘手的,而在困难的情况下则非常困难。确保您对将使用的语言有足够的了解,以便能够编写代码来正确处理复数问题。请记住,英语(以及其他“西方”语言是简单的语言之一。

  • 永远不要打断句子并用它们构建字符串以适应变量,因为变量可能以不同的语言放置在句子的其他地方。使用占位符。

  • 请记住,对于某些语言,占位符的值可能会改变句子的书写方式。语法很难。确保你有一个处理它的计划。(具体来说,确保您有办法根据性别、时间等对占位符中使用的值进行分类)。

于 2009-03-21T19:48:21.003 回答
9

我想发表以下评论 - 这些来自一些公司指南,其中 1 类产品在31个不同的语言环境中进行了翻译。遵循这些指导方针为我们(我们的开发团队而不是整个公司)提供了最高的翻译生产力。

  • 不要尝试重复使用错误消息片段。例如,不要以为因为你有两个错误"You selected the wrong menu item""That menu item is not yet available",你可以提取"menu item"到一个单独的项目中,并在两个地方都使用它。所有消息都应该是自包含的,因为它们的翻译可能会根据上下文而变化。

  • 使用熟悉技术的专业翻译人员。如果你靠近像 BabelFish 这样的服务,你会得到你应得的一切。例如,在地球"Microsoft Windows""Microsoft Windows"无处不在,它不会"Microsoft Fenster"在德国。

  • 尽量不要您的消息中嵌入变量(例如动态变化的"The %1 has failed"位置%1),因为位置,实际上,性别可能会改变:"La table est rubbish"vs."L'Homme est drunk""The red table"vs. "La table rouge"最好使用带有附加参数的通用名词:"The item has failed [%1]".

  • 只翻译用户期望看到的东西。日志文件中的日志消息(只有您会使用)应该是英语(或您的母语),而不是翻译成您无论如何都无法阅读的斯瓦希里语。

  • 菜单应按功能排序,而不是排序顺序。

  • 可翻译单元应存储在代码外部并在运行时加载。这使得翻译成为仅将外部文件发送出去的问​​题,而不是试图将更改硬塞到代码中间。它还使将来添加其他语言变得更加容易。

现在就足够了。最好在你们都睡着之前停下来:-)

于 2009-03-20T03:57:30.797 回答
8

关于数字的事情:据我所知,在英语中,您只需将单数与 1 一起使用,将复数与 2 或更多一起使用。比如:“你有 1 条消息”;“2 条消息”;“3...消息”。在俄语中,这些事情变得更加复杂。您对 1、21、31、41... 101、121 使用单数(因此,对于以 1 结尾的所有内容,除非以 11 结尾)。然后你对 2, 3, 4 使用单数属格;22、23、24;32、33、34……102、103、104;122、123、124。在所有其他情况下,您使用复数属格

实施起来并不难。然而,困难的是实现一些知道如何处理任何先验未知语言及其所有怪异的东西:-)

这只是数字:-)

于 2009-03-13T20:21:00.700 回答
6

到目前为止,我没有太多要补充的好答案,但这里有一些事情需要考虑和检查。

  • 不要做假设。 这是包罗万象的规则。很容易假设特定于地区或语言的事物,并且很难注意到这些假设。
  • 字符串比较要非常小心。 有一些语言,例如土耳其语,它们的字母在视觉上与其他语言相似,但又有所不同。
  • 使用伪翻译作为冒烟测试。 如果您从资源文件中读取已翻译的字符串,请创建一个您仍然可以理解的文件的伪翻译版本,但它强调应用程序中每个可翻译字符串的容量和能力。例如,用“CancelXXXX!”之类的内容填充“Cancel”之类的字符串。因此它与您对翻译字符串的允许范围一样宽。然后您可以测试以验证每个字符串都将完全显示。额外的功劳还在于坚持可能呈现的最复杂的字符,以验证它在所有地方都正确显示。
  • 不要对键盘布局做出假设。 “ASDW”可能是用于 QWERTY 键盘的一组很好的方向键控制集,但硬编码使得使用其他键盘布局的人不友好,如果不是不可能的话。
  • 测试各种日期设置,然后再次测试它们。 由于区域设置中“AM/PM”的不同格式,我已经看到了一些问题。mm/dd/yyyy vs. dd/mm/yyyy 也经常出现,但这里的每个设置都很重要。
  • 测试各种数字格式,然后再次测试。 例如,您不想依赖小数或千位分隔符。
  • 在有和没有用户登录到服务器的情况下进行测试。 这可能更特定于 Windows,但很容易在服务器上配置一个组件,以便在用户登录时使用登录用户的区域设置,在用户未登录时使用默认区域设置。这个可能会导致奇怪的间歇性行为。
  • 使用各种区域和语言设置进行测试。 例如,Windows 不仅有区域和语言设置,IE 也有自己的语言设置。例如,将 en-us 列在首位的 IE 客户端的行为可能并不总是与 en-nz 列在首位的 IE 客户端的行为相同。
  • 确保您的翻译人员了解业务和语言,然后与其他人交叉核对。 任何时候使用特定于应用程序的术语时都要非常小心。如果您的程序使用特定词来表示应用程序中的特殊内容,请确保它们在每个实例中都以相似的方式进行翻译,包括在帮助文本中。如果您有特定的语言目标,您甚至可以提前翻译这些词,并确保它们不会在目标语言中翻译得不好。这更像是一个产品研究的事情,但它可以改变界面中使用的单词,如果这些单词从一开始就到位,那么每个人都会更容易。您还想避免可能翻译不好的成语。

好吧,我想说的比我想象的要多……

于 2009-03-26T21:15:55.667 回答
5

我学到了一件事:如果您有多个文件需要翻译,请在名称中包含一个额外的标签,以便稍后您可以在整个文件夹中搜索该标签。

例如,不要将文件命名为“sample-database.txt”,而是将英文版命名为“sample-database-loc-en.txt”,将意大利文版命名为“sample-database-loc-it.txt”

于 2009-03-13T22:27:44.030 回答
4

我在 StackOverflow 中的第一个答案,如果有人说愚蠢,请原谅。

根据我的经验:

  • PHP:gettext 非常有用;
  • 非西方语言:UTF-8 无处不在(代码、数据库),到目前为止我们做得很好;
  • 您在实践中是否遇到过任何具体的问题?将 i18n 的长段落拆分成不同的句子可以降低翻译成本,如果字符串在网站中重复多次,您只需翻译一次。但是,要小心,如果你对文本进行过多的分割,翻译者会失去上下文;
  • 我见过很多项目和网站让他们的社区为他们的应用程序和内容提供翻译。你推荐这个吗?有什么好的策略来确保你有一个好的翻译?如果你有大量的志愿者,那就去吧,但根据你有多少文字,你可能真的需要大量的志愿者。还要始终确保您有一个您信任的人作为语言项目的领导者来担任控制翻译准确性的校对员。
于 2009-03-21T20:51:19.180 回答
3
  • 不同语言之间的排序规则/排序规则可能大相径庭:ä 在德语中的排序方式与在瑞典语中的排序方式不同。因此,排序需要针对特定​​文化。
  • 大写/小写可以带来惊喜:德语“sharp S”字符 ß 没有大写版本,要么转换为“SS”,要么在准确性很重要的情况下保持小写。土耳其语有一个无点的小写 i 和一个带点的大写 I。
  • 对于多语言 Web 应用程序,请仔细考虑如何确定要显示的版本以及如何将其用于 URL。用户应该始终能够手动选择语言,并且您希望搜索引擎在不同的 URL 下找到不同的语言版本。
  • 一些东亚语言(即日语和汉语,也许还有其他语言)在单词之间没有空格
  • 日语(也许还有其他人)有阿拉伯数字和空格的单独版本(“全角”),甚至有一些自己的字符的两个版本(半角和全角片假名)。
于 2009-05-05T21:14:58.703 回答
1

是的,这是一个庞大的主题。把它做好是一项非常艰巨的工作。

在我的程序中,我对每段文本都使用一个整数键,并根据需要在文件中查找它,具体取决于语言。代码中的任何地方都没有文字字符串,只有键。我用 C++ 中的“枚举”定义它们,所以我实际上并没有输入数字。当我添加更多枚举并且翻译者填写空白时,我编写了一个实用程序来同步各种语言文件。

每个键还具有关联的工具提示、图像、键盘快捷键等。

至于时间和日期……再一次,这比您想象的要复杂得多,但是 PHP 不为您处理这个问题吗?(我不知道,我是一个 C++ 人......)

于 2009-03-20T01:18:11.210 回答
1

PHP 在内部将字符串表示为字节流,并在编码很重要的情况下假定为 iso-8859-1。在大多数情况下,您可以在所有地方使用 UTF-8,就可以了。一个问题是,如果您的网站从用户那里获取输入,那么您永远无法 100% 确定他们以正确的编码提交内容。您可能想要使用mb_detect_encoding来验证输入,或使用带有“外来”字符的隐藏字段来验证。

请注意,PHP 中所有基于字符的字符串相关函数都假定字符 = 字节。这意味着您通常不能信任字符串函数。请查看此页面以获取更多详细信息。

PHP 的另一个好资源是Nick Nettleton 的备忘单

与字符集/编码密切相关的主题是 collat ​​ion。您需要您的排序规则来匹配您正在使用的语言/文化。至少在 MySql 中(可能在其他 RDBMS 中也是如此),您可以指定不同级别的排序规则,例如每个数据库、每个表、每个列,甚至在查询本身中。

于 2009-03-23T21:57:30.020 回答