java - 有没有半自动的方法来为 i18n 执行字符串提取?

标签 java string internationalization

我们有一个 Java 项目,其中包含大量用于用户提示、错误消息等的英文字符串。我们想将所有可翻译的字符串提取到一个属性文件中,以便稍后进行翻译。

例如,我们想要替换:

Foo.java

String msg = "Hello, " + name + "! Today is " + dayOfWeek;

与:

Foo.java

String msg = Language.getString("foo.hello", name, dayOfWeek);

language.properties

foo.hello = Hello, {0}! Today is {1}

我知道以完全自动化的方式执行此操作几乎是不可能的,因为并非每个字符串都应该被翻译。然而,我们想知道是否有一种半自动化的方法可以消除一些繁琐的工作。

最佳答案

您想要的是一个工具,它可以用一个库调用替换每个涉及字符串连接的表达式,以及只涉及单个文字字符串的表达式的明显特殊情况。

您可以在其中表达您想要的模式的程序转换系统可以做到这一点。 这样的系统接受以下形式的规则:

         lhs_pattern -> rhs_pattern  if condition ;

其中模式是对模式变量具有语法类别约束的代码片段。这会导致该工具查找与 lhs_pattern 匹配的语法,如果找到,则替换为 rhs_pattern,其中模式匹配是针对语言结构而不是文本。因此,无论代码格式、缩进、注释等如何,它都能正常工作。

草拟一些规则(并过度简化以保持简短) 按照你的例子的风格:

  domain Java;

  nationalize_literal(s1:literal_string):
    " \s1 " -> "Language.getString1(\s1 )";

  nationalize_single_concatenation(s1:literal_string,s2:term):
    " \s1 + \s2 " -> "Language.getString1(\s1) + \s2"; 

  nationalize_double_concatenation(s1:literal_string,s2:term,s3:literal_string): 
      " \s1 + \s2 + \s3 " -> 
      "Language.getString3(\generate_template1\(\s1 + "{1}" +\s3\, s2);"
   if IsNotLiteral(s2);

模式本身包含在“...”中;这些不是 Java 字符串文字,而是一种对多计算机语言模式匹配引擎说的方式 “...”中的后缀是(域)Java 代码。元数据标有\, 例如,元变量\s1,\s2,\s3 和嵌入模式调用\generate 用 ( 和 ) 来表示它的元参数列表:-}

请注意元变量 s1 和 s3 上语法类别约束的使用,以确保仅匹配字符串文字。元变量在左侧模式中匹配的内容在右侧被替换。

子模式 generate_template 是一个过程,它在转换时(例如,当规则触发时)将其已知为常量的第一个参数评估为您建议的模板字符串并插入到您的库中,并返回一个库字符串索引。 请注意,生成模式的第一个参数是此示例完全由串联的文字字符串组成。

显然,必须有人手动处理最终出现在库中的模板化字符串,以生成外语等价物。
你是对的,这可能会使代码过度模板化,因为某些字符串不应该放在国家化的字符串库中。在您可以为这些情况编写程序检查的范围内,可以将它们作为条件包含在规则中以防止它们触发。 (稍加努力,您可以将未转换的文本放入评论中,从而使以后更容易撤消单个转换)。

实际上,我猜你必须编写 ~~100 条这样的规则才能涵盖组合学和感兴趣的特殊情况。返回是您的代码会自动得到增强。如果做得好,您可以在代码经历多个版本时重复将此转换应用于您的代码;它会保留以前的国有化表达式,只修改由无忧无虑的程序员插入的新表达式。

可以做到这一点的系统是 DMS Software Reengineering Toolkit . DMS 可以解析/模式匹配/转换/ pretty-print 许多语言,包括 Java 和 C#。

关于java - 有没有半自动的方法来为 i18n 执行字符串提取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1011423/

相关文章:

java - 用于蒙特卡罗模拟的 matlab 代码到 java 的翻译

c++ - 在 C++ 中传递 C 字符串的问题

javascript - 是否有用于 Javascript 字符串的反向连接运算符?

html - 使用浏览器,我如何知道操作系统使用哪个小数点分隔符?

java - 没有任何 ORM 的延迟加载/初始化设计模式

Java 2D : Why won't my JPanel let me resize it?

java - 通过单击两个不同的按钮来调用同一个 servlet 以从同一个数据库获取数据

c++ - wchar_t 对字符串的位操作

java - Spring MVC 3 localeChangeInterceptor

ruby-on-rails - Rails 4 : pluralizing model_name. 人类使用计数:123 不起作用