String
텍스트로 객체를 전달할 수있는 Java에 대체 메커니즘 이 있습니까? 문자열이 발생하면이를 대체합니다.
예를 들어 텍스트는 다음과 같습니다.
Hello ${user.name},
Welcome to ${site.name}.
내가 가진 개체는 "user"
및 "site"
입니다. 내부 ${}
에 주어진 문자열을 객체의 동등한 값 으로 바꾸고 싶습니다 . 이것은 속도 템플릿에서 객체를 교체하는 것과 같습니다.
String
텍스트로 객체를 전달할 수있는 Java에 대체 메커니즘 이 있습니까? 문자열이 발생하면이를 대체합니다.
예를 들어 텍스트는 다음과 같습니다.
Hello ${user.name},
Welcome to ${site.name}.
내가 가진 개체는 "user"
및 "site"
입니다. 내부 ${}
에 주어진 문자열을 객체의 동등한 값 으로 바꾸고 싶습니다 . 이것은 속도 템플릿에서 객체를 교체하는 것과 같습니다.
Hello ${user.name}
, not like Hello %s
또는 Hello {0}
.
답변:
StringSubstitutor
Apache Commons Text에서 사용합니다 .
https://commons.apache.org/proper/commons-text/
그것은 당신을 위해 할 것입니다 (그리고 오픈 소스 ...)
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}.";
StringSubstitutor sub = new StringSubstitutor(valuesMap);
String resolvedString = sub.replace(templateString);
Map<String, String> valuesMap = new HashMap<String, String>();
합니다.
StrSubstitutor
이제 https://commons.apache.org/proper/commons-lang/ 에서 더 이상 사용되지 않습니다 . 사용자 https://commons.apache.org/proper/commons-text/ 대신
StrSubstitutor
1.3부터 더 이상 사용되지 않으므로 StringSubstitutor
대신 사용하십시오. 이 클래스는 2.0에서 제거됩니다. 가져 오기에 대한 Gradle을 의존성 StringSubstitutor
이다org.apache.commons:commons-text:1.4
java.text.MessageFormat
클래스를 살펴보면 MessageFormat은 개체 집합을 가져 와서 형식을 지정한 다음 형식이 지정된 문자열을 적절한 위치의 패턴에 삽입합니다.
Object[] params = new Object[]{"hello", "!"};
String msg = MessageFormat.format("{0} world {1}", params);
format
또한 걸리는 Object...
이 더 간결한 구문 곳 바람직 사용할 수 있도록 변수 인수format("{0} world {1}", "Hello", "!");
MessageFormat
기술적 형식이 중요한 출력이 아닌 이름을 딴 디스플레이 메시지에만 안정적으로 사용할 수 있다는 점에 유의해야합니다 . 예를 들어 숫자는 로케일 설정에 따라 형식이 지정되어 기술적 용도로 사용할 수 없습니다.
내가 선호하는 방법은 String.format()
oneliner이고 타사 라이브러리가 필요하지 않기 때문입니다.
String message = String.format("Hello! My name is %s, I'm %s.", name, age);
예를 들어 다음과 같은 예외 메시지에서 정기적으로 사용합니다.
throw new Exception(String.format("Unable to login with email: %s", email));
힌트 : Varargs를format()
사용 하기 때문에 원하는만큼 변수를 입력 할 수 있습니다.
String.format("Hello! My name is %s, I'm %s. Why is my name %s you ask? Well I'm only %s years old so I don't know", name, age, name, age);
. 여기에있는 다른 답변은 각 인수를 한 번만 지정해야합니다.
String.format("Hello! My name is %1$s, I'm %2$s. Why is my name %1$s you ask? Well I'm only %2$s years old so I don't know", name, age)
나는 이것의 작은 테스트 구현을 함께 던졌다. 기본 아이디어는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가 무엇인지 모른다는 것을 언급해야 하므로이 답변이 관련이 있기를 바랍니다.
이 작업을 수행하는 방법에 대한 개요가 있습니다. 실제 코드로 구현하는 것은 비교적 간단해야합니다.
이 작업을 수행하는 몇 가지 Expression Language 구현이 있습니다. 자체 구현을 사용하거나 요구 사항이 증가하면 JUEL 및 MVEL을 참조하십시오.
적어도 하나의 프로젝트에서 MVEL을 좋아하고 성공적으로 사용했습니다.
또한 비 JSP (독립 실행 형) 컨텍스트 에서 Stackflow 게시물 JSTL / JSP EL (Expression Language)을 참조하십시오.
속도는 그 문제를 정확히 해결하기 위해 작성 되었기 때문에 속도에 필적하는 즉시 사용할 수있는 것은 없습니다. 시도 할 수있는 가장 가까운 방법은 Formatter를 살펴 보는 것입니다.
그러나 내가 아는 한 포맷터는 Java에서 포맷 옵션과 같은 C를 제공하기 위해 만들어 졌으므로 가려움증을 정확히 긁지 않을 수 있지만 시도해 볼 수 있습니다 :).
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);
String.format("Hello %s", username);