java中的字符串替换,类似于速度模板

时间:2010-09-07 02:48:46

标签: java string reflection velocity

Java中是否有任何String替换机制,我可以使用文本传递对象,并在发生时替换字符串。
例如,文本是:

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

我拥有的对象是"user""site"。我想将${}中给出的字符串替换为对象中的等效值。这与我们在速度模板中替换对象相同。

9 个答案:

答案 0 :(得分:112)

使用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);

答案 1 :(得分:110)

看一下java.text.MessageFormat类,MessageFormat获取一组对象,格式化它们,然后将格式化的字符串插入到适当位置的模式中。

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

答案 2 :(得分:17)

我把这个小测试实现了。基本思想是调用format并传入格式字符串,对象映射及其本地名称。

以下输出为:

  

我的狗被命名为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));
    }
}

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

另外,我不喜欢你必须自己在代码中构建地图,但我不知道如何以编程方式获取局部变量的名称。最好的方法是记住在创建对象后立即将对象放入地图中。

以下示例从您的示例中生成您想要的结果:

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是什么,所以我希望这个答案是相关的。

答案 3 :(得分:5)

以下是您如何做到这一点的概述。将它实现为实际代码应该相对简单。

  1. 创建将在模板中引用的所有对象的地图。
  2. 使用正则表达式在模板中查找变量引用,并将其替换为其值(请参阅步骤3)。 Matcher类将为查找和替换派上用场。
  3. 在点处拆分变量名称。 user.name将成为username。在地图中查找user以获取对象,并使用reflection从对象中获取name的值。假设您的对象具有标准getter,您将查找方法getName并调用它。

答案 4 :(得分:5)

我的首选方式是 String.format() ,因为它是一个单行:

String result = String.format("Hello! My name is %s, I'm %s.", NameVariable, AgeVariable); 

我经常在异常消息中使用它,例如:

throw new Exception(String.format("Unable to login with email: %s", email));

提示:由于format()使用Varargs

,因此您可以输入任意多个变量

答案 5 :(得分:4)

有几种表达式语言实现可以为您完成此操作,可能更适合使用您自己的实现,或者如果您的需求增长,请参阅JUELMVEL

我喜欢并且已经在至少一个项目中成功使用过MVEL。

另请参阅Stackflow帖子JSTL/JSP EL (Expression Language) in a non JSP (standalone) context

答案 6 :(得分:0)

没有任何开箱即可与速度相媲美,因为写入速度来解决这个问题。您可以尝试的最接近的事情是查看Formatter

http://cupi2.uniandes.edu.co/site/images/recursos/javadoc/j2se/1.5.0/docs/api/java/util/Formatter.html

然而,就我所知,格式化程序是为了在Java中提供类似C的格式化选项而创建的,所以它可能不会划伤你的痒但是欢迎你尝试:)。

答案 7 :(得分:0)

我在Java中使用GroovyShell使用Groovy GString解析模板:

Binding binding = new Binding();
GroovyShell gs = new GroovyShell(binding);
// this JSONObject can also be replaced by any Java Object
JSONObject obj = new JSONObject();
obj.put("key", "value");
binding.setProperty("obj", obj)
String str = "${obj.key}";
String exp = String.format("\"%s\".toString()", str);
String res = (String) gs.evaluate(exp);
// value
System.out.println(str);

答案 8 :(得分:0)

我创建了这个使用 vanilla Java 的实用程序。它将 String.format.... 中的两种格式... {}%s 样式合并到一个方法调用中。请注意,它仅替换空的 {} 括号,而不是 {someWord}

public class LogUtils {

    public static String populate(String log, Object... objects) {
        log = log.replaceAll("\\{\\}", "%s");
        return String.format(log, objects);
    }

    public static void main(String[] args) {
        System.out.println(populate("x = %s, y ={}", 5, 4));;
    }

}