
说实话,我刚接触本地化翻译那会儿,对"字符串"这个概念是模糊的。总觉得不就是把英文翻成中文嘛,能有多复杂?后来发现,事情完全不是我想的那样。软件里的字符串跟Word文档里的文字根本不是一回事,它有自己的脾气,有自己的规则,也有自己的陷阱。
今天我想用比较接地气的方式聊聊,软件本地化翻译到底是怎么处理字符串的。这里会用一些康茂峰在实践中积累的经验,尽量把那些技术性的东西讲得通俗易懂。
简单说,字符串就是软件界面里那些会被翻译的文字。但它远不止是"显示在屏幕上的字"这么简单。
举个很常见的例子。你打开一个软件,界面上有个按钮写着"OK"。这个词看起来够简单了吧?但如果我告诉你,这个"OK"在不同的语境下可能需要翻译成完全不同的词,你会怎么想?
有些情况下,"OK"就是确认的意思,翻译成"确定"或者"好"就行。但有些情况下,"OK"可能是一个状态标识,比如"设置已保存,状态为OK",这时候它可能需要翻译成"正常"或者"成功"。还有更极端的情况,这个"OK"根本不需要翻译,保持英文就行。
这就是软件字符串的诡异之处。同样的字串,在不同的上下文里可能有完全不同的处理方式。所以本地化翻译的第一步,往往不是拿起键盘就翻,而是先把字符串的来龙去脉搞清楚。

软件开发的时候,程序员写代码会把界面上要显示的文字单独存放在资源文件里,而不是硬编码在程序逻辑中。这种做法的好处是,修改界面文字不需要改动程序代码,翻译的时候也只需要处理这些专门的资源文件。
常见的资源文件格式有很多,比如Windows系统常用的RESX和RC文件,Java程序用的PROPERTIES文件,网页应用常见的JSON和XML文件,还有苹果系统用的STRINGS文件。每种格式都有自己的特点,提取工具也各不相同。
提取字符串这个环节看似简单,实际上坑很多。有些字符串是可见的,用户能直接看到;有些则是隐藏的,只有在特定操作后才会显现。提示信息、错误消息、菜单项、按钮标签、帮助文档,这些都属于需要翻译的内容,但它们的格式和位置可能完全不同。
更有意思的是,同一个字符串可能在代码里被引用好多次。这时候如果翻译不统一,就会出现界面混乱的问题。比如一个程序把"Cancel"在界面上显示为"取消",在某个下拉菜单里却显示为"放弃",用户肯定会觉得这个软件做得太糙了。
如果说普通的字符串是本地化的入门关卡,那含有变量和占位符的字符串就是进阶挑战。这东西有多烦人呢?
让我举个例子。软件开发中经常会有这样的提示信息:"您有%d条新消息"。这里的%d是一个占位符,实际运行时会替换成具体的数字,比如"您有5条新消息"。如果只翻译字面意思,翻成"你有条新消息",那到时候显示出来就会是"您有5条新消息",少了个量词,语法都错了。
更复杂的情况是多个变量共存。比如"来自%s的消息:%s",这里有两个%s,第一个是发送者名字,第二个是消息内容。翻译的时候不仅要考虑两个变量各自的位置,还要考虑它们之间的标点和分隔方式。
不同的编程语言对变量的标记方式也不一样。有的用%d表示整数,有的用%s表示字符串,有的用%f表示浮点数。还有用花括号的,比如{0}、{1},或者用命名占位符的写法{name}、{count}。翻译人员需要了解这些不同的写法,才能在翻译时正确处理每个占位符的位置。

这里有个关键原则:占位符的位置可以调整,但占位符本身绝对不能删改或移动。举个反例,如果原字符串是"Show {0} of {1} results",有人翻成了"显示{1}条结果中的第{0}条",虽然读起来好像也通顺,但程序运行时会出错,因为变量替换的顺序变了。
英语的复数规则相对简单,大多数词加s或es就行。所以英文软件里经常能看到类似"1 file(s)"这样的写法,通过括号里的s来兼顾单数和复数。但这种方法在翻译时会遇到问题,因为不是所有语言都这么处理复数的。
俄语有三种复数形式,分别对应不同的数字区间。阿拉伯语的复数形式更多,高达六种。波兰语的复数形式则取决于数字的最后几位数字,而不仅仅是数字本身。这意味着同一个词,根据数字的不同,可能需要完全不同的翻译。
有些语言根本没有复数概念,或者复数形式和单数完全一样。遇到这种情况,翻译时就需要根据目标语言的语法规则来调整,而不是机械地把原文的复数形式翻译过去。
好的本地化工具会提供专门的复数形式编辑界面,让翻译人员可以为同一条字符串提供多个翻译版本,每个版本对应不同的数字规则。但这就要求翻译人员不仅要懂源语言和目标语言,还要了解目标语言の数词变化规则。
本地化翻译最痛苦的事情之一,就是拿到一条字符串,却完全不知道它会用在哪里。
我举个例子。假设有这么一条字符串:"Drive"。这个词在技术文档里可能指的是硬盘分区,在汽车相关的软件里可能指的是驾驶行为,在游戏里可能指的是关卡或赛道。如果没有任何上下文,翻译人员只能靠猜,猜对了皆大欢喜,猜错了就等着被测试人员报bug吧。
康茂峰的本地化团队在处理这类情况时,通常会建立一套上下文收集机制。翻译开始前,会和开发团队沟通,获取界面截图、用途说明、使用场景等信息。有些比较规范的项目,还会在资源文件里用注释的方式标注每个字符串的用途。
但现实总是比理想骨感。很多项目的字符串注释要么不完整,要么干脆没有。这时候有经验的翻译人员会怎么做?他们会去分析字符串所在的代码模块、关联的变量名称、所在的界面位置,从这些信息里反向推断可能的含义。
如果推断不出来怎么办?最好的办法是标注为"待确认",等项目负责人提供更多信息再处理。硬着头皮随便翻一个,虽然可能省了一时的事,但后续返工的成本往往会更高。
除了文字内容,软件界面里还有大量需要格式化的数据,比如数字、日期、时间、货币。这些东西看起来是"数",实际上是"文",同样需要翻译处理。
先说日期格式。美国人习惯月/日/年,比如10/31/2024代表2024年10月31日。但欧洲很多国家用的是日/月/年,同一个日期就会写成31/10/2024。如果软件界面直接显示"10/31",美国人理解为10月31日,欧洲人则会认为是10月31日这个日期有问题,因为他们的月份不可能到31。
货币格式的差异也很有意思。美国用美元符号$放在数字前面,欧洲用欧元符号€有的放在前面有的放在后面,日本用円或者¥但通常不加符号。千分位的分隔符也不同,美国用逗号,欧洲用句号。2,000在英语里是两千,在德语里则是二点零,也就是二。
这些格式化内容有些是在翻译阶段处理,有些则需要在程序代码里处理。本地化翻译人员需要了解目标地区的习惯写法,确保显示出来的格式符合当地用户的认知。
软件字符串处理还有一个容易被人忽视的领域,就是字符编码。看起来都是字,但其实背后的存储方式各不相同。
英语国家用ASCII编码就足够了,但中文、日文、韩文这些需要CJK字符集的语言,必须用Unicode编码才能正确显示。如果源语言的编码和目标语言的编码不匹配,就会出现乱码,翻译内容完全不可读。
更麻烦的是有些语言有特殊的字符变体。比如德语的ß,既可以写成单个字符ß,也可以写成ss。土耳其语有带点和不带点的i。俄语的某些字母在不同词形下会有不同的形状。这些细节如果处理不当,轻则显示不美观,重则影响文本搜索和排序功能。
另外,字符串的长度限制也常常是个问题。英文翻译成中文后,字符长度通常会缩短30%到50%,这一般是好事。但反过来,如果从中文翻译成某些使用拉丁字母的语言,文字可能会变长。原来按钮上刚好能显示的文字,翻译后可能就超出一截,显示不完整。
很多人以为翻译完就是把译文交给客户就完事了。但在专业的本地化流程里,翻译只是其中一个环节,后面还有一系列的测试和验证工作。
功能测试是最基本的检查。要在目标语言的操作系统上运行软件,查看所有界面元素是否正确显示,文字是否完整,有没有任何乱码或截断。特别要关注那些动态生成的字符串,比如用户操作后弹出的提示信息,这些往往是问题高发区。
语言测试则是检查译文本身的准确性和自然度。翻译是否准确传达了原文含义?是否符合目标语言的习惯表达?有没有生硬或者不通顺的地方?界面上的文字和其他地方是否保持一致的译法?
技术测试则关注字符串在实际运行中的表现。变量占位符是否正确替换?复数形式是否根据实际数字显示正确的版本?日期和数字的格式是否符合当地习惯?这些都需要在真实的使用场景中验证。
康茂峰的项目流程通常会安排多轮测试,每轮测试后修复发现的问题,直到所有测试项都通过。这个过程可能会持续好几轮,但确保最终交付的产品质量是有保障的。
说了这么多流程和挑战,最后聊聊支撑这些工作的工具。
p>翻译记忆工具是本地化的标配。它能记住之前翻译过的句子和短语,遇到相似的句子时自动给出参考译文。这样不仅提高了效率,还保证了同一术语在不同地方的译文一致性。术语管理工具则负责管理项目的专业词汇表。遇到新术语时,系统会自动检查是否在术语库中有标准译法,如果有就采用,没有就新增或者标注待确认。这样一来,整个项目的术语翻译都会保持统一。
质量检查工具则可以在翻译完成后自动扫描,发现常见的错误。比如漏译、译文过长、标点符号使用不当、变量占位符丢失或位置错误等等。这些工具虽然不能替代人工审校,但能 catch 到很多低级错误,提高整体质量。
软件本地化翻译的字符串处理,说到底就是一场跨语言、跨技术、跨文化的协调工作。它既需要对语言的敏感,也需要对技术的理解;既要有追根究底的精神,也要有处理繁琐细节的耐心。
好的本地化不是简单地把一种文字换成另一种,而是让软件在另一种语言环境里用起来,就像本来就是为那个语言和那个文化设计的一样。这背后涉及到的字符串处理工作,看似不起眼,实则是其中非常关键的一环。
如果你正在做或者准备做软件本地化,希望这篇文章能帮你少走一些弯路。有些坑,只有踩过才知道疼;而有些经验,听别人讲一句,可能就能省下好几天返工的时间。
