Java中Python字符串'Template'的等效实现
Python支持以下操作:
>>> s = Template('$who likes $what')
>>> s.substitute(who='tim', what='kung pao')
'tim likes kung pao'
(这个例子来自Python的官方文档)
在Java中有没有类似的方法可以完成同样的任务呢?
谢谢
6 个回答
这里还有一个其他的选项,详细内容可以在这里找到。为了方便,我再重复一下。
有一个库叫做 org.apache.commons:commons-text:1.9,里面有个类叫 StringSubstitutor。它的工作原理是这样的:
// Build map
Map<String, String> valuesMap = new HashMap<>();
valuesMap.put("animal", "quick brown fox");
valuesMap.put("target", "lazy dog");
String templateString = "The ${animal} jumped over the ${target}.";
// Build StringSubstitutor
StringSubstitutor sub = new StringSubstitutor(valuesMap);
// Replace
String resolvedString = sub.replace(templateString);
不过有一点需要注意。StringSubstitutor
实例是通过一个替换映射创建的,然后用它的 replace
方法来解析模板字符串。这意味着它不能提前解析模板字符串,所以如果用不同的替换映射处理同一个模板,可能会效率较低。
而Python的 string.Template
则是相反的工作方式。它是通过模板字符串创建的,然后用它的 substitute
或 safe_substitute
方法来处理替换映射。所以理论上它可以提前解析模板字符串,这样可能会提高性能。
另外,Python的 string.Template
默认会处理 $variable
或 ${variable}
。目前还没找到如何调整 StringSubstitutor
让它也这样处理。
默认情况下,StringSubstitutor
会解析值中的占位符,这可能会导致无限循环。可以通过 stringSubstitutor.setDisableSubstitutionInValues(true)
来禁用这种行为。
我不知道有没有完全相同的东西,但你可以这样做:
String s = "$who likes $what";
s.replace("$who", "tim").replace("$what", "kung pao");
这样做你会得到一样的结果。
Chunk模板(http://www.x5dev.com/chunk)让这类操作变得非常简单:
Chunk c = new Chunk();
c.append("{$who} likes {$what}");
c.set("who", "tim");
c.set("what", "kung pao");
String output = c.toString();
或者如果你已经有一个 Map<String,String>
的话:
Chunk c = new Chunk();
c.append("{$who} likes {$what}");
Map<String,String> tagValues = getTagValues();
c.setMultiple(tagValues);
c.render(System.out);
Chunk还方便从文件或一组文件中加载模板,并且支持循环、分支和展示过滤器。
你可以去看看这个网站:http://www.stringtemplate.org/。这里有一个例子:
ST hello = new ST("Hello, <name>");
hello.add("name", "World");
System.out.println(hello.render());
这个例子会输出:
"Hello World"
这段代码的意思是,我们可以用一种简单的方式来格式化字符串,也就是把一些变量放进一个句子里。
比如,第一行代码:
String s = String.format("%s likes %s", "tim", "kung pao");
这里我们创建了一个字符串,内容是“tim likes kung pao”,也就是“tim喜欢宫保鸡丁”。
第二行代码:
System.out.printf("%s likes %s", "tim", "kung pao");
这行代码的作用是直接在控制台上打印出同样的内容,而不是把它存到一个变量里。
总之,这两种方法都可以很方便地把变量放进一个句子里,形成我们想要的内容。
String s = "%s likes %s";
String.format(s, "tim", "kung pao");