我有一个来自API或存储在我的数据库中的String,我想在运行时用我的标签替换所有标签。有没有有效的方法来实现这一目标?
使用if else
效率不高,因为我的模型有超过100个字段。
String rawText= "Hello %name% !, Nice to meet you! Your age is %age%."
我想用我的模型中存储的值替换所有%____%
文本。
class Person{
private String name;
private String age;
getter...
setter....
}
答案 0 :(得分:2)
您可以使用反射按名称获取字段值:
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String replaceTags(String rawText) {
Matcher m = Pattern.compile("%(.+?)%").matcher(rawText);
boolean result = m.find();
if (result) {
StringBuffer sb = new StringBuffer();
do {
m.appendReplacement(sb, Matcher.quoteReplacement(getField(m.group(1))));
result = m.find();
} while (result);
m.appendTail(sb);
return sb.toString();
}
return rawText.toString();
}
private String getField(String name) {
try {
return String.valueOf(this.getClass().getDeclaredField(name).get(this));
} catch (Exception e) {
throw new IllegalArgumentException("could not read value for field: " + name);
}
}
}
如果您使用的是Java 9,则可以使用替换函数简化replaceTags()
:
public String replaceTags(String rawText) {
return Pattern.compile("%(.+?)%").matcher(rawText)
.replaceAll(r -> Matcher.quoteReplacement(getField(r.group(1))));
}
如果您有像Jackson这样的JSON序列化库,您可以使用它来自动处理反射,并按字段名称构建值映射:
Map<String, Object> fieldValues = new ObjectMapper()
.convertValue(this, new TypeReference<Map<String, Object>>() {});
答案 1 :(得分:2)
使用反射你可以用几行代码来完成:
import java.lang.reflect.Field;
public class Main {
public static void main(String arg[]) throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException {
String rawText= "Hello %name% !, Nice to meet you! Your age is %age%.";
Field[] fields = Person.class.getFields();
Person person = new Person("TestName", "TestAge");
for(Field field: fields) {
rawText = rawText.replace("%"+field.getName()+"%", (String)field.get(person));
}
}
}
只需在Person类中公开字段。
答案 2 :(得分:1)
你可以使用replaceAll
String rawText= "Hello %name% !, Nice to meet you! Your age is %age%.";
rawText = rawText.replaceAll("%name%", "new name");
rawText = rawText.replaceAll("%age%", "new age");
新名称和新年龄可以来自您的模型。
答案 3 :(得分:0)
我认为没有任何理由说明常规字符串连接在这里是不够的。只需在Person
中定义一个帮助器方法,它使用给定人员的属性构建输出字符串:
public class Person {
// ...
public String getGreeting() {
StringBuilder sb = new StringBuilder("");
sb.append("Hello ").append(name).append(", nice to meet you! Your age is ");
sb.append(age).append(".");
return sb.toString();
}
}