I am trying to format String in java using MessageFormat
class. The String contains positional field but it only work if I provide the field number. For e.g
MessageFormat.format("{0} {1}", "Hi", "Java")
works but
MessageFormat.format("{} {}", "Hi", "Java")
gives
Exception in thread "main" java.lang.IllegalArgumentException: can't parse argument number:
at java.text.MessageFormat.makeFormat(MessageFormat.java:1429)
at java.text.MessageFormat.applyPattern(MessageFormat.java:479)
at java.text.MessageFormat.<init>(MessageFormat.java:362)
at java.text.MessageFormat.format(MessageFormat.java:840)
at controller.App.main(App.java:11)
Caused by: java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:592)
at java.lang.Integer.parseInt(Integer.java:615)
at java.text.MessageFormat.makeFormat(MessageFormat.java:1427)
Is there a way(any other class or library) in that it can handle both automatic and manual field numbering something like python does?
In [3]: print "{} {}".format("Hi", "Java")
Hi Java
In [4]: print "{0} {1}".format("Hi", "Java")
Hi Java
I'd use the pattern posted by Maroun Maroun if I was confined to standard libraries like barunsthakur.
Ben Greens clever idea is useful for everyone who uses sfl4j when logging with non-indexed arguments, in addition to preparing strings manually with indexed arguments.
There was one disadvantage for me: I can use both indexed and non-indexed arguments now, but I'm not able to use the FormatType and FormatStyle options from java.text.MessageFormat.format(), e.g. {0,number,currency}.
So I made up an extended version of Ben's solution, that utilizes all 3 variants.
import org.slf4j.helpers.MessageFormatter;
import java.text.MessageFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public static String format(String original, Object... replacements)
{
if (Pattern.matches(".*\\{\\d+,.+,.+\\}.*", original))
{
return MessageFormat.format(original, replacements);
}
else
{
String r = "\\{\\d\\}";
if(original.matches(".*" + r + ".*"))
{
Pattern p = Pattern.compile(r);
Matcher m = p.matcher(original);
StringBuffer b = null;
int i = 0;
while(m.find())
{
if(b == null) b = new StringBuffer();
m.appendReplacement(b, replacements[i].toString());
i++;
}
m.appendTail(b);
return (i > 0) ? b.toString() : null;
}
else
{
return MessageFormatter.arrayFormat(original, replacements).getMessage();
}
}
}
Unit-Tests:
String expected = "pink is a disgusting color";
String actual = StringHelpers.format("{0} is a disgusting {1}", "pink", "color");
assertEquals(expected, actual);
expected = "01-02-2017 was a rather meh day";
actual = StringHelpers.format("{0,date,MM-dd-YYYY} was a rather {1} day", new Date(117,0,2), "meh");
assertEquals(expected, actual);
expected = "One Person expects the danish inquisition";
actual = StringHelpers.format("{} expects the {} inquisition", "One Person", "danish");
assertEquals(expected, actual);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With