Neatbo.

平台翻译占位符对照

按 Android Java Formatter 或 Apple NSString 语法对照成对字符串,检查参数顺序、类型和格式变化。

浏览器本地处理输入字符串配对 JSON输出JSON / CSV单个文件最多 1 MiB · 最多 1 个
  1. 1添加输入
  2. 2调整设置
  3. 3获取结果

工具输入和文件在当前浏览器处理,不会上传。

输入内容

切换工具时在当前标签页临时保留输入。刷新或关闭后清除,较大的结果可能需要重新生成。

⌘ / Ctrl + Enter 运行

或将文件拖到这里

文件留在当前设备,原始文件不会被覆盖。

.json

单个文件最多 1 MiB · 最多 1 个

    0 个字符 · 0 字节
    处理选项

    先填写标记为必填的选项,其余可保留默认值。

    正在准备处理工具…

    开始之前

    在运行前找出译文改变参数或遗漏百分号的情况。选择实际平台,输入源文与译文配对,并检查需要人工确认的差异。

    如何使用

    1. 选择 Android Java Formatter 或 Apple NSString,粘贴 {key?,source,target} JSON 数组。
    2. 检查参数、格式和字面 token 的差异;显式位置占位符可在签名不变时调整顺序。
    3. 下载审查报告,并在目标应用中验证实际参数值与类型。

    支持范围与限制

    一个 UTF-8 JSON 文件或粘贴数组,不超过 1 MiB,最多 10,000 对。每项包含 source、target 和可选唯一 key;key 最多 256 个 UTF-16 单元。每串最多 1,000 个 token,合计最多 100,000 个。所选文件优先。 JSON 解析另有 200,000 节点、128 层预算。

    Android 支持 Java 通用 b/h/s、字符 c、整数 d/o/x、浮点 e/f/g/a 及文档中的 t/T 日期后缀和对应大写形式,支持 n$ 显式位置、独立普通序号、< 复用、静态宽度/精度、%%、%n。检查转换特定标志及重复冲突;显式索引与 < 同时出现会明确拒绝,不推断实际参数类型兼容性。

    Apple 支持 @、d/D、u/U、x/X、o/O、f/F、e/E、g/G、a/A、c/C、s/S、p、%%,以及声明范围内的静态标志/宽度/精度、整数 hh/h/l/ll/q/z/t/j 和浮点 L 长度。混合位置/普通参数、动态 * 宽度精度、< 复用、%n、宽字符长度别名及不支持的标志组合会使整次处理失败。

    分别对照参数/转换/长度的出现次数、标志/宽度/精度,以及百分号/换行字面 token。格式变化是待审查结果,不自动改写,也不能证明实际运行必然错误。不提取 XML/strings 文件,不解析 ICU、不翻译、不执行格式化。预览显示 200 对,JSON 保留所有 token 位置和差异。

    操作示例

    示例输入

    [
      {
        "key": "reordered",
        "source": "%1$s has %2$d files %%",
        "target": "%2$d 个文件,%1$s %%"
      },
      {
        "key": "type",
        "source": "%1$s: %2$d",
        "target": "%1$s: %2$s"
      },
      {
        "key": "precision",
        "source": "%1$.2f",
        "target": "%1$.3f"
      }
    ]
    示例参数
    {"params": {"platform": "android"}}

    示例输出

    {
      "platform": "android",
      "scope": "finite platform Formatter/NSString syntax; signature comparison only, no rendering or runtime type guarantee",
      "records": [
        {
          "key": "reordered",
          "source": "%1$s has %2$d files %%",
          "target": "%2$d 个文件,%1$s %%",
          "sourceTokens": [
            {
              "raw": "%1$s",
              "offset": 0,
              "argument": 1,
              "conversion": "s",
              "length": "",
              "flags": "",
              "width": null,
              "precision": null
            },
            {
              "raw": "%2$d",
              "offset": 9,
              "argument": 2,
              "conversion": "d",
              "length": "",
              "flags": "",
              "width": null,
              "precision": null
            },
            {
              "raw": "%%",
              "offset": 20,
              "argument": null,
              "conversion": "%",
              "length": "",
              "flags": "",
              "width": null,
              "precision": null
            }
          ],
          "targetTokens": [
            {
              "raw": "%2$d",
              "offset": 0,
              "argument": 2,
              "conversion": "d",
              "length": "",
              "flags": "",
              "width": null,
              "precision": null
            },
            {
              "raw": "%1$s",
              "offset": 9,
              "argument": 1,
              "conversion": "s",
              "length": "",
              "flags": "",
              "width": null,
              "precision": null
            },
            {
              "raw": "%%",
              "offset": 14,
              "argument": null,
              "conversion": "%",
              "length": "",
              "flags": "",
              "width": null,
              "precision": null
            }
          ],
          "argumentsDifference": [],
          "formatDifference": [],
          "literalDifference": false,
          "status": "match"
        },
        {
          "key": "type",
          "source": "%1$s: %2$d",
          "target": "%1$s: %2$s",
          "sourceTokens": [
            {
              "raw": "%1$s",
              "offset": 0,
              "argument": 1,
              "conversion": "s",
              "length": "",
              "flags": "",
              "width": null,
              "precision": null
            },
            {
              "raw": "%2$d",
              "offset": 6,
              "argument": 2,
              "conversion": "d",
              "length": "",
              "flags": "",
              "width": null,
              "precision": null
            }
          ],
          "targetTokens": [
            {
              "raw": "%1$s",
              "offset": 0,
              "argument": 1,
              "conversion": "s",
              "length": "",
              "flags": "",
              "width": null,
              "precision": null
            },
            {
              "raw": "%2$s",
              "offset": 6,
              "argument": 2,
              "conversion": "s",
              "length": "",
              "flags": "",
              "width": null,
              "precision": null
            }
          ],
          "argumentsDifference": [
            {
              "signature": [
                2,
                "d",
                ""
              ],
              "sourceCount": 1,
              "targetCount": 0
            },
            {
              "signature": [
                2,
                "s",
                ""
              ],
              "sourceCount": 0,
              "targetCount": 1
            }
          ],
          "formatDifference": [
            {
              "signature": [
                2,
                "d",
                "",
                "",
                null,
                null
              ],
              "sourceCount": 1,
              "targetCount": 0
            },
            {
              "signature": [
                2,
                "s",
                "",
                "",
                null,
                null
              ],
              "sourceCount": 0,
              "targetCount": 1
            }
          ],
          "literalDifference": false,
          "status": "review"
        },
        {
          "key": "precision",
          "source": "%1$.2f",
          "target": "%1$.3f",
          "sourceTokens": [
            {
              "raw": "%1$.2f",
              "offset": 0,
              "argument": 1,
              "conversion": "f",
              "length": "",
              "flags": "",
              "width": null,
              "precision": 2
            }
          ],
          "targetTokens": [
            {
              "raw": "%1$.3f",
              "offset": 0,
              "argument": 1,
              "conversion": "f",
              "length": "",
              "flags": "",
              "width": null,
              "precision": 3
            }
          ],
          "argumentsDifference": [],
          "formatDifference": [
            {
              "signature": [
                1,
                "f",
                "",
                "",
                null,
                2
              ],
              "sourceCount": 1,
              "targetCount": 0
            },
            {
              "signature": [
                1,
                "f",
                "",
                "",
                null,
                3
              ],
              "sourceCount": 0,
              "targetCount": 1
            }
          ],
          "literalDifference": false,
          "status": "review"
        }
      ]
    }

    出现问题时

    选择真实平台,修正第一个不支持或不合法 token。动态宽度需要其他明确合同或原生运行验证。Apple 参数应统一使用显式位置或普通顺序,并提供唯一配对 key。

    常见问题

    review 一定代表翻译错误吗?

    不一定。它提示签名或格式改变,需要明确决定;重复引用或精度变化可能是有意设计。

    Android 的 < 复用能用于 Apple 字符串吗?

    不能。两种语法独立,Apple 请使用支持的显式位置占位符。

    会检查 ICU 大括号或读取翻译资源文件吗?

    不会。请提供已经解码的 printf 风格字符串,ICU 和资源提取需要各自的格式合同。

    文档与延伸阅读

    相关工具