String.format
String str = String.format("Action %s occured on object %s.",
objectA.getAction(), objectB);
Or
String str = String.format("Action %s occured on object %s with outcome %s.",
new Object[]{objectA.getAction(), objectB, outcome});
You can also use numeric positions, for example to switch the parameters around:
String str = String.format("Action %2$s occured on object %1$s.",
objectA.getAction(), objectB);
Answer from The Scrum Meister on Stack OverflowVideos
String.format
String str = String.format("Action %s occured on object %s.",
objectA.getAction(), objectB);
Or
String str = String.format("Action %s occured on object %s with outcome %s.",
new Object[]{objectA.getAction(), objectB, outcome});
You can also use numeric positions, for example to switch the parameters around:
String str = String.format("Action %2$s occured on object %1$s.",
objectA.getAction(), objectB);
You can use String.format or MessageFormat.format
E.g.,
MessageFormat.format("A sample value {1} with a sample string {0}",
new Object[] {"first", 1});
or simply
MessageFormat.format("A sample value {1} with a sample string {0}", "first", 1);
This is normally solved with just a String#replaceAll, but since you have a custom, dynamic replacement string, you can to use a Matcher to efficiently and concisely do the string replacement.
public static String parse(String command, String... args) {
StringBuffer sb = new StringBuffer();
Matcher m = Pattern.compile("\\$(\\d+)").matcher(command);
while (m.find()) {
int num = Integer.parseInt(m.group(1));
m.appendReplacement(sb, args[num - 1]);
}
m.appendTail(sb);
return sb.toString();
}
Ideone Demo
A simple, inefficient solution is to iterate over the replacement array, looking for #1, #2 etc:
String[] arr = new String[]{"one","two","three"};
String toReplace = "first $1 second $2 third $3";
for (int i =0; i<arr.length;i++){
toReplace = toReplace.replaceAll("\\$"+(i+1), arr[i]);
}
System.out.println(toReplace);
Output:
first one second two third three
A more efficient approach would be to iterate once over the input string itself. Here's a quick and dirty version:
String[] arr = new String[]{"one","two","three"};
String toReplace = "first $1 second $2 third $3";
StringBuilder sb = new StringBuilder();
for (int i=0;i<toReplace.length();i++){
if (toReplace.charAt(i)=='#' && i<toReplace.length()-1){
int index = Character.digit(toReplace.charAt(i+1),10);
if (index >0 && index<arr.length){
sb.append(arr[index]);
continue;
}
}
sb.append(toReplace.charAt(i));
}
System.out.println(toReplace);
Output:
first one second two third three
That link you provided is an excellent source since matching using patterns is the way to go. The basic idea here is first get the tokens using a matcher. After this you will have Operators and Operands
Then, do the replacement individually on each Operand.
Finally, put them back together using the Operators.
A somewhat tedious solution would be to scan for all occurences of A and B and note their indexes in the string, and then use StringBuilder.replace(int start, int end, String str) method. (in naive form this would not be very efficient though, approaching smth like square complexity, or more precisely "number of variables" * "number of possible replacements")
If you know all of your operators, you could do split on them (like on "+") and then replace individual "A" and "B" (you'd have to do trimming whitespace chars first of course) in an array or ArrayList.
You can always use String.format(....). i.e.,
String string = String.format("A String %s %2d", aStringVar, anIntVar);
I'm not sure if that is attractive enough for you, but it can be quite handy. The syntax is the same as for printf and java.util.Formatter. I've used it much especially if I want to show tabular numeric data.
This is called string interpolation; it doesn't exist as such in Java.
One approach is to use String.format:
String string = String.format("A string %s", aVariable);
Another approach is to use a templating library such as Velocity or FreeMarker.
I really don't think you need to use a templating engine or anything like that for this. You can use the String.format method, like so:
String template = "Hello %s Please find attached %s which is due on %s";
String message = String.format(template, name, invoiceNumber, dueDate);
The most efficient way would be using a matcher to continually find the expressions and replace them, then append the text to a string builder:
Pattern pattern = Pattern.compile("\\[(.+?)\\]");
Matcher matcher = pattern.matcher(text);
HashMap<String,String> replacements = new HashMap<String,String>();
//populate the replacements map ...
StringBuilder builder = new StringBuilder();
int i = 0;
while (matcher.find()) {
String replacement = replacements.get(matcher.group(1));
builder.append(text.substring(i, matcher.start()));
if (replacement == null)
builder.append(matcher.group(0));
else
builder.append(replacement);
i = matcher.end();
}
builder.append(text.substring(i, text.length()));
return builder.toString();