java中的stringreplace,类似于速度模板

在Java中是否存在任何Stringreplace机制,我可以在其中使用文本传递对象,并在string出现时replacestring。
例如,文本是:

 Hello ${user.name}, Welcome to ${site.name}. 

我有的对象是"user""site" 。 我想用${}给出的stringreplace对象中的等价值。 这与我们replace速度模板中的对象相同。

使用apache commons lang。

https://commons.apache.org/proper/commons-lang/

它会为你做(和它的开源…)

  Map<String, String> valuesMap = new HashMap<String, String>(); valuesMap.put("animal", "quick brown fox"); valuesMap.put("target", "lazy dog"); String templateString = "The ${animal} jumped over the ${target}."; StrSubstitutor sub = new StrSubstitutor(valuesMap); String resolvedString = sub.replace(templateString); 

看一下java.text.MessageFormat类,MessageFormat接受一组对象,对它们进行格式化,然后将格式化的string插入到适当位置的模式中。

 Object[] params = new Object[]{"hello", "!"}; String msg = MessageFormat.format("{0} world {1}", params); 

我把这个小testing实现放在一起。 其基本思想是调用format并传入格式string,对象映射以及本地名称。

以下的输出是:

我的狗叫Fido,Jane Doe拥有他。

 public class StringFormatter { private static final String fieldStart = "\\$\\{"; private static final String fieldEnd = "\\}"; private static final String regex = fieldStart + "([^}]+)" + fieldEnd; private static final Pattern pattern = Pattern.compile(regex); public static String format(String format, Map<String, Object> objects) { Matcher m = pattern.matcher(format); String result = format; while (m.find()) { String[] found = m.group(1).split("\\."); Object o = objects.get(found[0]); Field f = o.getClass().getField(found[1]); String newVal = f.get(o).toString(); result = result.replaceFirst(regex, newVal); } return result; } static class Dog { public String name; public String owner; public String gender; } public static void main(String[] args) { Dog d = new Dog(); d.name = "fido"; d.owner = "Jane Doe"; d.gender = "him"; Map<String, Object> map = new HashMap<String, Object>(); map.put("d", d); System.out.println( StringFormatter.format( "My dog is named ${d.name}, and ${d.owner} owns ${d.gender}.", map)); } } 

注意:由于未处理的exception,这不会编译。 但它使代码更容易阅读。

另外,我不喜欢你必须在代码中自己构造映射,但我不知道如何以编程方式获得本地variables的名称。 要做到这一点,最好的办法是记得一旦创build它就把对象放在地图上。

以下示例根据示例生成所需的结果:

 public static void main(String[] args) { Map<String, Object> map = new HashMap<String, Object>(); Site site = new Site(); map.put("site", site); site.name = "StackOverflow.com"; User user = new User(); map.put("user", user); user.name = "jjnguy"; System.out.println( format("Hello ${user.name},\n\tWelcome to ${site.name}. ", map)); } 

我还要提一下,我不知道Velocity是什么,所以我希望这个答案是相关的。

以下是你如何能够做到这一点的大纲。 将它作为实际代码来实现应该相对简单。

  1. 创build将在模板中引用的所有对象的映射。
  2. 使用正则expression式在模板中查找variables引用,并将其replace为它们的值(请参阅步骤3)。 Matcher类将派上用场,find和replace。
  3. 在点处拆分variables名称。 user.name将成为username 。 在地图上查找user以获取对象并使用reflection从对象中获取name的值。 假设你的对象有标准的getter,你会查找getName方法并调用它。

有一些expression式语言实现在那里为您做这个,可能比使用自己的实现更好,或者如果您的需求增长,请参阅例如JUEL和MVEL

我喜欢并至less在一个项目中成功使用了MVEL。

另请参见非JSP(独立)上下文中的Stackflow post JSTL / JSP EL(expression式语言)

没有任何东西可以与速度相比较,因为速度是为了解决这个问题而写的。 你可以尝试的最接近的东西是查看格式化程序

http://cupi2.uniandes.edu.co/sitehttp://img.dovov.comrecursos/javadoc/j2se/1.5.0/docs/api/java/util/Formatter.html

然而,据我所知,格式化程序是为了在Java中提供类似于格式化选项的C语言,所以它可能不会正确地抓取您的痒,但欢迎您尝试:)。