i18n 语言包互转
JSON、properties、YAML、TS 语言包互转,键对齐与占位符一致性检查。
输入侧认五种读法(默认自动识别,判错时用「读作」下拉框固定):扁平键 JSON、嵌套 JSON、YAML、Java .properties、CSV/TSV(一列一种语言,表头即语言名)。输出侧七种:扁平键 JSON、嵌套 JSON、YAML、.properties、CSV、TSV 与 export default … as const 的 TS 模块。摊平与还原按点号路径做,反向拼树只在键段安全时进行;识别、转换、对照全在浏览器内存里完成,不发请求,也不执行粘贴进来的任何代码。
JSON 用的是自写的宽松解析器,模板字符串、变量引用、字符串拼接读不了,会带着行列号报错而不是猜;拼嵌套树时 __proto__ / constructor / prototype 一律拒绝输出(写进嵌套结构等于改原型链),路径冲突的键逐条列出并不写入结果。对照表不比值的类型——非字符串在摊平阶段已成文本,这点如实说明;检查只比较、绝不改写任何一侧的文案,ICU 复数只标记不解析,${…} 引用(Spring/Vue 插值)不跟随解析。
i18n 语言包互转怎么用
- 先固定读法再转换:自动识别是启发式(制表符占比、等号占比、缩进行为等),把 YAML 读成 properties 时用「读作」下拉框钉死即可。左侧主包必填;右侧对照包留空就只转换、不出对照表(此时「对照表」分段按钮直接是灰的),「与对照包互换」把基准换到另一侧,缺失与多出的方向随之翻转。
- 多语言 CSV/TSV:多列输入的 CSV/TSV 本次只转换第一个语言列;导出侧的列是 key 加主包与对照包,单包导出是 key,主包 两列(列头用「主包」这个标签,不是 value)。要把全部语言放进一张表,就把各语言列逐个作为对照包放右侧,或直接以 CSV/TSV 形态搬运。
- 取值方式:本页没有复制按钮:结果区是普通可选中文本,meta 行跟着视图走——「输出」视图报键数、输出格式与字节数,切到「对照表」报的是对照行数与语言清单(N 行 · zh-CN / en-US 这样)。另有「下载文本」按所选输出格式补扩展名。
- 摊平与还原的口径:嵌套对象 a.b.c 摊平成键,数组下标写成 a.b[2],空对象与空数组都摊平成一条空值并记账(数组没有下标可摊,不给空值就会整条消失)。「数字键还原成数组」开关决定连续的 0…n 键拼回 JSON/YAML/TS 里的真数组还是保持对象形态。值不是字符串(数字/布尔/null)的条目按字面文本搬运,转换后仍是字符串。CSV/TSV 的空单元格按「这个语言没有这个键」处理,与「值是空字符串」是两回事。
- 对照表的分区与上限:输出与对照表共用一块空间,点结果卡标题旁那组「输出|对照表」分段按钮才切过去,没有对照数据时「对照表」是灰的、自动落回输出。基准永远是左侧主包、其余只与它比:主包有而对照包没有记「缺失」,对照包独有的键记「多出」,值只有空白记「空值」,两边都有才比对占位符。对照表最多列 400 行,超出注明截断;键序有原顺序/字典序/按首段分组三种,缩进可选 2 格、4 格或不换行。
常见问题
.properties 里的 \uXXXX 转义和值里的 = 为什么常把别的工具带进坑?
Java 的规则是第一个未被转义的 = 、: 或空白才是分隔符,值里的 = 本来不需要转义,用 split("=") 取第二段这类朴素写法会把值截断甚至丢掉后半段;\uXXXX、\t、\n 不还原就会出现「键对得上、值是乱码」;行尾反斜杠还得数奇偶——偶数个是字面反斜杠,奇数个才是续行。本工具按这套口径找分隔符与解转义,空键跳过、重复键保留最后一次并记账。输出侧反过来:键里的 = : # ! 与行首空格加反斜杠,值里的反斜杠、换行、制表符转义,非 ASCII 按 UTF-8 原样写;老 Java 默认 ISO-8859-1 加 \u 转义的读法需要对侧编码配置配合。
ICU 复数和 ${…} 引用为什么不解析、不重排?
复数求值(one/other/#、offset、=0 精确匹配)由运行时按每种语言自己的复数形式表决定,静态改写等于替几百种语言拍板,改错的代价比不改大得多,所以工具只给 ICU 条目计数、整串原样搬运。${a} 这类引用指向另一个键,跟随解析就要处理 a→b→a 的循环和指向缺失键的引用,工具选择把它当占位符原样搬运:对照表里参与比较,但不展开、不改写。占位符识别 printf 的 %s %d 等与位置型 %1$s(%% 不算占位符)、gettext 的 %(name)s、%{name}、{{name}}、${name}、{name},外加 ICU 的 {x, plural / select / selectordinal, …} 与复数、序数分支里的 #(select 分支里的 # 按普通字符处理);各家族分开记账,{name} 与 {{name}} 混用会被判成不一致,这是有意的——它们由不同的运行时解析器消费。
为什么有的键在嵌套 JSON/YAML/TS 输出里不见了?
拼嵌套树时有两种情况会被拒绝并逐条列在提示里:键段撞上 __proto__ / constructor / prototype(写进 JS 对象等于改原型链),以及路径冲突——同一个前缀既当过叶子值又当过分支(比如同时存在 a 和 a.b),或点号键拆出的层级与数组下标对不上。被拒绝的键不会静默改名、也不会塞进别的层级,这是刻意的「不猜」。想一条不丢就输出扁平键 JSON 或 .properties。
读入侧按什么规则解析?
properties 按 Java 口径解析:= : 与空白都能作分隔符,# 与 ! 是注释,行尾奇数个反斜杠按续行拼接,\t \n \uXXXX 还原成字符;一行没有分隔符时整行当键名、值为空。JSON 用的是自写的宽松解析器:无引号键、单引号、尾逗号、行注释与块注释、export default / const x = 前缀都读得动,所以静态书写的 TS/JS 语言包可以作为输入。
键的顺序、重复键与输出转义怎么处理?
数字形态的键单独记账:交给 JS 对象处理会按数值顺序重排并优先输出,本工具自己拼字符串、按文本顺序保留;YAML 输入经过 js-yaml 变成 JS 值,这类键的原顺序无法还原,提示里写明。properties 里重复的键后值覆盖前值、保留最后一次并记一笔;JSON 文本里的重复键逐个记账、值按最后一次生效但位置保持第一次出现,提示里点名(一次最多列 8 个键)。properties 输出只转义键里的分隔符与值里的反斜杠、换行、制表符、行首空格,非 ASCII 按 UTF-8 原样写、不重新编码成 \uXXXX。
对应功能编号 #24无需安装,手机端同样可用按 Ctrl + K 换工具