Замена строк в java, аналогично шаблону скорости
Есть ли какой-либо механизм замены String
в Java, где я могу передавать объекты с текстом, и он заменяет строку по мере ее возникновения.
Например, текст:
Hello ${user.name}, Welcome to ${site.name}.
Объекты, которые у меня есть, – "user"
и "site"
. Я хочу заменить строки, указанные внутри ${}
эквивалентными значениями из объектов. Это то же самое, что мы заменяем объекты в шаблоне скорости.
- Является ли строка Java действительно неизменной?
- Как отрегулировать ведущее / завершающее пробелы стандартным образом?
- Пакет / Поиск и редактирование строк в TXT-файле
- Формат метода (String, Object ) в типе String не применим для аргументов (...)
- Заполнение строк в C
- Как отформатировать строку Java с начальным нулем?
- как преобразовать строку в дату в mysql?
- ef4 причина Циркулярная ссылка в веб-службе
- Что рекурсивно распространяется на все файлы в текущем каталоге?
- Преобразование секретного ключа в строку и наоборот
- Что означает {0}, когда он найден в строке в C #?
- Байт Java-массива с массивом строк в байт
- Снижение производительности String.intern ()
Используйте apache commons lang.
https://commons.apache.org/proper/commons-lang/
Он сделает это за вас (и с открытым исходным кодом …)
Map valuesMap = new HashMap(); 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);
Взгляните на class java.text.MessageFormat
, MessageFormat принимает набор объектов, форматирует их, а затем вставляет форматированные строки в шаблон в соответствующих местах.
Object[] params = new Object[]{"hello", "!"}; String msg = MessageFormat.format("{0} world {1}", params);
Я бросил вместе небольшую тестовую реализацию этого. Основная идея состоит в том, чтобы вызывать format
и передавать строку формата, а также карту объектов и имена, которые у них есть локально.
Вывод следующего:
Моя собака называется fido, и Джейн Доу владеет им.
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 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 map = new HashMap(); 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 map = new HashMap(); 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). Класс « Матчи » пригодится для поиска и замены.
- Разделите имя переменной в точке.
user.name
станетuser
иname
. Найдитеuser
на своей карте, чтобы получить объект и использовать reflection, чтобы получить значениеname
из объекта. Предполагая, что у ваших объектов есть стандартные геттеры, вы будете искать методgetName
и вызывать его.
Существует несколько реализаций языка выражений, которые делают это для вас, может быть предпочтительнее использовать вашу собственную реализацию по мере того, как ваши требования растут, см., Например, JUEL и MVEL
Мне нравится и успешно использовал MVEL, по крайней мере, в одном проекте.
Также см. Сообщение Stackflow post JSTL / JSP EL (язык выражений) в контексте не JSP (автономный)
Нет ничего из коробки, сравнимого со скоростью, так как скорость была написана для решения именно этой проблемы. Самое близкое, что вы можете попробовать, – это посмотреть в Formatter
Однако форматировщик, насколько мне известно, был создан для обеспечения C как форматирования на Java, поэтому он может не царапать ваш зуд, но вы можете попробовать :).