Замена строки в java, аналогично шаблону скорости
есть String
механизм замены в Java, где я могу передать объекты с текстом, и он заменяет строку, как это происходит.
Например, текст :
Hello ${user.name},
Welcome to ${site.name}.
объекты у меня есть "user"
и "site"
. Я хочу заменить строки, приведенные внутри ${}
С эквивалентными значениями из объектов. Это то же самое, что мы заменяем объекты в шаблоне скорости.
6 ответов:
используйте 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 принимает набор объектов, форматирует их, а затем вставляет отформатированные строки в шаблон в соответствующих местах.Object[] params = new Object[]{"hello", "!"}; String msg = MessageFormat.format("{0} world {1}", params);
я собрал небольшую тестовую реализацию этого. Основная идея состоит в том, чтобы позвонить
format
и передать в строке формата и карту объектов, и имена, которые они имеют локально.вывод следующего:
мою собаку зовут Фидо, и она принадлежит Джейн Доу.
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)); }
я должен также упомянуть, что я понятия не имею, что такое скорость, поэтому я надеюсь, что этот ответ уместен.
вот набросок того, как вы могли бы это сделать. Это должно быть относительно просто реализовать его как фактический код.
- создайте карту всех объектов, на которые будут ссылаться в шаблоне.
- используйте регулярное выражение, чтобы найти ссылки на переменные в шаблоне и заменить их своими значениями (см. Шаг 3). Элемент Matcher класс пригодится для поиска и замены.
- разделить имя переменной в точка.
user.name
станетuser
иname
. Посмотри вверхuser
в вашей карте, чтобы получить объект и использовать отражение чтобы получить значениеname
из объекта. Предполагая, что ваши объекты имеют стандартные геттеры, вы будете искать способgetName
и вызывать его.
есть несколько реализаций языка выражений, которые делают это для вас, может быть предпочтительнее использовать вашу собственную реализацию, как или если ваши требования растут, см. например JUEL и MVEL
Я люблю и успешно использовал MVEL по крайней мере в одном проекте.
Также см. сообщение Stackflow JSTL / JSP EL (язык выражений) в не JSP (автономном) контексте
нет ничего из коробки, что сопоставимо с скоростью так как скорость была написана, чтобы решить именно эту проблему. Самое близкое, что вы можете попробовать, это заглянуть в форматер
однако форматер, насколько я знаю, был создан для обеспечения C, как параметры форматирования в Java, так что он не может поцарапать точно ваш зуд, но вы добро пожаловать, чтобы попробовать :).