
做软件本地化这事儿,咱康茂峰的团队干了这么些年,见识过各种各样的坑。有些错误看起来挺傻的,但真遇上了能让你加班到半夜。今天咱们就聊聊那些在实际项目里反复出现的毛病,不是什么高深的理论,就是一些血淋淋的教训。
这是最基本也是最难缠的问题。同一个Save按钮,前面翻译成保存,后面变成储存,再后面又成了另存为。用户用起来那叫一个迷糊,总觉得软件精神分裂了。
这事儿往往不是因为翻译水平不行,而是协作出了问题。一个中等规模的软件可能有上千条字符串,分给五六个译者,要是没有术语库(Term Base)管着,每个人都按自己的习惯来,最后出来的产品就像拼凑的百家衣。
康茂峰处理过一个案例,客户的产品里Dashboard这个词,在导航菜单里叫仪表盘,在设置里叫控制面板,到了帮助文档里又成了驾驶舱视图。这么搞下来,技术支持电话被打爆了,用户以为这是三个不同的功能。

英文Save就四个字符,翻成中文保存也是俩字,看着挺和谐。但遇到Check for Updates这种,中文检查更新勉强能用,要是德语Nach Updates suchen,好家伙,一下子长了一倍。
很多开发者在设计界面时只考虑英文,按钮宽度写死了。翻译一装进去,要么文字被截断显示成检查更...,要么直接溢出到隔壁按钮上头,界面变得跟抽象画似的。
更隐蔽的是字符串拼接。有些程序员喜欢写"Save" + " " + filename这样的代码。在英语里没问题,但翻译成日语,保存后面接文件名,语法上可能需要助词,硬拼接出来的句子读起来像个结巴。
| 英文原文 | 中文翻译 | 德文翻译 | 膨胀率 |
| Save | 保存 | Speichern | +125% |
| Settings | 设置 | Einstellungen | +150% |
| Undo last action | 撤销上一步 | Letzte Aktion rückgängig machen | +280% |
康茂峰的建议是:做伪本地化(Pseudo-localization)测试。在翻译前先用假语言(比如把英文字母换成带重音符号的版本)跑一遍,看看界面会不会崩。这比等到真翻译来了才发现问题要省钱得多。
软件本地化不只是换语言,是换文化语境。这个坑太深了,很多团队栽进去都不知道自己是怎么栽的。
美国人是MM/DD/YYYY,欧洲人是DD/MM/YYYY,日本人可能是YYYY/MM/DD。如果你的软件把日期03/04/2024显示给用户,美国人以为是3月4号,英国人以为是4月3号。这在金融软件里是要命的错误。
千位分隔符在英语国家是逗号,小数点是句点。但在德国和法国刚好反过来。€1.000在德国人眼里是一千欧元,在美国人眼里就是带着奇怪空格的一欧元。康茂峰见过有软件因为这个被退货,因为财务对不上账。
绿色在大部分地方代表通过/成功,但在某些东亚文化里,绿色跟丧葬有关。 thumbs-up(竖大拇指)的手势在某些中东国家是严重的冒犯。这些不是翻译错误,是文化适配错误,但后果同样严重。
这是最让译者无奈的情况。拿到的翻译文件里只有单个的单词或短语,没有任何上下文。
比如Filter这个词,可以是名词过滤器,也可以是动词过滤。在资源文件里孤零零一个Filter,译者只能猜。猜错了,界面上就会出现语法不通顺的句子,比如请选择一个过滤器器或者请过滤这个列表器。
还有一词多义的问题。Key可以是钥匙、键盘按键、关键,或者是密码学里的密钥。Second可以是第二秒,也可以是二手的。没有注释(Context Comment),译者就像在黑暗里打靶。
康茂峰的做法是要求开发团队在提取字符串时,必须带上注释。哪怕就写一句// This is a button to filter search results,也比什么都没强。更进一步,能提供截图的绝不只给文字,视觉上下文能省掉百分之五十的来回沟通。
有些字符串根本没放进资源文件(resource file),而是直接写在代码里。比如错误提示"File not found"直接写在C++代码的cout里,而不是放在strings.xml或者.resx文件里。
这些硬编码的字符串在翻译阶段完全看不见,测试阶段如果按正常路径走也可能测不出来。只有用户触发了那个特定的错误条件,才会突然蹦出一句英文,破坏了整个本地化的完整性。
对付这个得靠国际化(i18n)审计。在康茂峰的项目流程里,翻译开始前必须先做代码扫描,把所有硬编码的文本揪出来。工具像Lint、dgettext扫描都能帮忙,但最保险的还是人工检查,特别是那些错误处理和边缘情况的代码。
英语和中文的复数比较简单,一般就加s或者单复数同形。但有些语言的复数规则复杂得吓人。
斯拉夫语系(俄语、波兰语、捷克语等)通常有三种复数形式:单数、2-4的复数、5以上的复数。阿拉伯语更多。如果你的代码只准备了%d file和%d files两种形式,遇到波兰语就傻眼了——波兰语里1 plik(单数),2-4 pliki(一种复数),5-21 plików(另一种复数)。
还有性别问题。法语、德语、西班牙语里,名词有阴阳性,形容词和冠词要跟着变。软件里的用户在法语里是l'utilisateur(阳性)或l'utilisatrice(阴性),如果 your software just says "The user is...,后面接的形容词可能是content(阳性)或contente(阴性)。如果你不知道用户性别,就得用被动语态或者重新组织句子。
康茂峰建议用ICU MessageFormat这类标准来处理复数、选择性和占位符,别自己发明轮子写if-else判断,不然维护起来是个灾难。
很多团队觉得翻译稿一交,装进去能显示中文,本地化就算完了。太天真了。
你得测功能测试:换了语言后功能还正常吗?有些代码依赖字符串比较,比如if (status == "Active"),这种代码在中文版里一定会崩,因为Active被翻译成活跃了,字符串匹配不上。
得测布局测试:所有文字都显示完整吗?有没有重叠?从右到左的语言(RTL,比如阿拉伯语、希伯来语)有没有把界面镜像过来?
还得测输入测试:用户用本地语言输入法输入内容,软件能正确处理吗?双字节字符(中文、日文、韩文)会不会被截断或者变成问号?
康茂峰见过最离谱的bug是软件支持中文界面,但数据库字段只给留了varchar(50),存50个字母没问题,存50个汉字就超长了,因为UTF-8编码下汉字占3个字节。这种坑在单元测试阶段根本发现不了,只有在集成测试里用真实数据才能踩出来。
最后说个容易被忽略的:帮助文档、用户手册跟软件界面不一致。界面上的按钮改了名字,文档里没改;或者截图还是英文版的,文字描述却是中文的。
这种不一致性比纯英文界面还讨厌,因为用户按照文档操作,发现点的地方和文档说的不一样,会产生是不是我下载错了版本的怀疑。信任就是这么一点点磨没的。
康茂峰的做法是建立术语库的联动机制,UI变了,文档必须跟着变,而且用截图自动更新工具,确保视觉参照永远是准的。虽然这招增加了前期工作量,但省下了后期客服解释的成本。
说到底,软件本地化翻译不是简单的语言转换,是系统工程。从代码架构的国际化准备,到翻译流程的质量控制,再到测试验证的闭环,每个环节都可能埋下错误的种子。把上面说的这些坑都填平了,你的产品才能真正在海外用户手里用得顺手,而不是成为一个笑话。
