是否有类似于sl4fj的通用字符串替换函数?

kmc*_*coy 75 java

使用sl4fj,如果我想构造一个字符串消息,有一个很好的方法,它使用替换.例如,它可能是这样的:

logger.info("Action {} occured on object {}.", objectA.getAction(), objectB);
Run Code Online (Sandbox Code Playgroud)

如果需要更多的替换,那么它是这样的:

logger.info("Action {} occured on object {} with outcome {}.", 
    new Object[]{objectA.getAction(), objectB, outcome});
Run Code Online (Sandbox Code Playgroud)

我的问题是:是否有一种通用的方式来创建一个字符串(而不仅仅是一个slf4j日志消息)?就像是:

String str = someMethod("Action {} occured on object {}.", objectA.getAction(), objectB);
Run Code Online (Sandbox Code Playgroud)

要么

String str = someMethod("Action {} occured on object {} with outcome {}.", 
    new Object[]{objectA.getAction(), objectB, outcome});
Run Code Online (Sandbox Code Playgroud)

如果它在标准Java库中,那么"someMethod"会是什么?

The*_*ter 101

的String.format

String str = String.format("Action %s occured on object %s.",
   objectA.getAction(), objectB);
Run Code Online (Sandbox Code Playgroud)

要么

String str = String.format("Action %s occured on object %s with outcome %s.",
   new Object[]{objectA.getAction(), objectB, outcome});
Run Code Online (Sandbox Code Playgroud)

您也可以使用数字位置,例如切换参数:

String str = String.format("Action %2$s occured on object %1$s.",
   objectA.getAction(), objectB);
Run Code Online (Sandbox Code Playgroud)


Joh*_*erg 42

您可以使用String.formatMessageFormat.format

例如,

MessageFormat.format("A sample value {1} with a sample string {0}", 
    new Object[] {"first", 1});
Run Code Online (Sandbox Code Playgroud)

或者干脆

MessageFormat.format("A sample value {1} with a sample string {0}", "first", 1);
Run Code Online (Sandbox Code Playgroud)


小智 24

如果您正在寻找一个解决方案,您可以使用值替换String中的一堆变量,您可以使用StrSubstitutor.

 Map<String, String> 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);
Run Code Online (Sandbox Code Playgroud)

它遵循一个普遍接受的模式,其中可以将带有变量的映射与未解析的String一起传递给值,并返回已解析的String.


Pet*_*ete 15

我建议使用org.slf4j.helpers.MessageFormatter.在它的帮助下,可以创建一个使用与slf4j完全相同的格式样式的utillity方法:

// utillity method to format like slf4j
public static String format(String msg, Object... objs) {
    return MessageFormatter.arrayFormat(msg, objs).getMessage();
}

// example usage
public static void main(String[] args) {
    String msg = format("This msg is {} like slf{}j would do. {}", "formatted", 4,
            new Exception("Not substituted into the message"));

    // prints "This msg is formatted like slf4j would do. {}"    
    System.out.println(msg); 
}
Run Code Online (Sandbox Code Playgroud)

注意:如果数组中的最后一个对象是异常,它将不会在消息中被替换,就像使用slf4j记录器一样.可通过以下方式访问例外MessageFormatter.arrayFormat(msg, objs).getThrowable().

  • 我认为这不是一个很好的通用答案,但是实际上已经达到了要求的程度。 (2认同)
  • 我发现这是正确的答案。就性能而言,这应该是最好的。 (2认同)
  • 最佳答案,因为它使用问题所要求的确切语法。 (2认同)