Sim*_*son 13 java string internationalization
我们有一个Java项目,其中包含大量用于用户提示,错误消息等的英语字符串.我们希望将所有可翻译的字符串提取到属性文件中,以便以后可以翻译它们.
例如,我们想要替换:
Foo.java
String msg = "Hello, " + name + "! Today is " + dayOfWeek;
Run Code Online (Sandbox Code Playgroud)
有:
Foo.java
String msg = Language.getString("foo.hello", name, dayOfWeek);
Run Code Online (Sandbox Code Playgroud)
language.properties
foo.hello = Hello, {0}! Today is {1}
Run Code Online (Sandbox Code Playgroud)
我知道以完全自动化的方式完成此操作几乎是不可能的,因为不是每个字符串都应该被翻译.但是,我们想知道是否有一种半自动化方式可以消除一些劳动力.
您想要的是一个工具,它可以用库调用替换涉及字符串连接的每个表达式,以及仅涉及单个文字字符串的表达式的明显特殊情况。
您可以在其中表达所需模式的程序转换系统可以做到这一点。这样的系统接受以下形式的规则:
lhs_pattern -> rhs_pattern if condition ;
Run Code Online (Sandbox Code Playgroud)
其中模式是对模式变量具有语法类别约束的代码片段。这会导致该工具查找与 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);
Run Code Online (Sandbox Code Playgroud)
模式本身包含在“...”中;这些不是 Java 字符串文字,而是向多计算机语言模式匹配引擎表明“...”内的内容是(域)Java 代码的一种方式。元数据用 \ 标记,例如元变量 \s1、\s2、\s3 和嵌入模式调用 \generate 用 ( 和 ) 表示其元参数列表 :-}
请注意对元变量 s1 和 s3 使用语法类别约束以确保仅匹配字符串文字。元变量在左侧模式中匹配的内容将在右侧进行替换。
子模式generate_template是一个过程,在转换时(例如,当规则触发时)将其已知的常量第一个参数评估为您建议的模板字符串并插入到您的库中,并返回库字符串索引。请注意,生成模式的第一个参数是此示例完全由连接的文字字符串组成。
显然,有人必须手动处理最终出现在库中的模板化字符串以生成外语等效项。
您是对的,这可能会过度模板化代码,因为某些字符串不应该放置在国家化字符串库中。如果您可以为这些情况编写编程检查,则可以将它们作为条件包含在规则中以防止触发它们。(只需付出一点努力,您就可以将未转换的文本放入注释中,从而使以后更容易撤消单独的转换)。
实际上,我猜你必须编写 ~~100 个这样的规则才能涵盖组合数学和感兴趣的特殊情况。回报是您的代码会自动得到增强。如果做得正确,当您的代码经历多个版本时,您可以重复地将这种转换应用于您的代码;它将保留以前的国有化表达式,而只是修改无忧无虑的程序员插入的新表达式。
DMS Software Reengineering Toolkit是一个可以做到这一点的系统。DMS 可以解析/模式匹配/转换/漂亮打印许多语言,包括 Java 和 C#。