GWT中的string格式化程序

我如何格式化我的string在GWT?

我做了一个方法

Formatter format = new Formatter(); int matches = 0; Formatter formattedString = format.format("%d numbers(s, args) in correct position", matches); return formattedString.toString(); 

但它抱怨说

 Validating newly compiled units [ERROR] Errors in 'file:/C:/Documents%20and%20Settings/kkshetri/workspace/MasterMind/MasterMind/src/com/kunjan/MasterMind/client/MasterMind.java' [ERROR] Line 84: No source code is available for type java.util.Formatter; did you forget to inherit a required module? 

是不是格式化程序?

更新:请看(并投票)约瑟夫Lust的职位之前,进一步看这个答案。

看起来像格式化不包括根据这个职位 。 但是,他们build议一些替代scheme。

请参阅GWTdate和数字格式的官方页面 。

他们build议如下:

 myNum decimal = 33.23232; myString = NumberFormat.getFormat("#.00").format(decimal); 

最好是使用他们支持的优化方法,而不是制作自己的非最优方法。 无论如何,他们的编译器将会把它们全部优化成几乎相同的东西。

GWT 2.1+中一个非常简单的replaceString.format()

 import com.google.gwt.regexp.shared.RegExp; import com.google.gwt.regexp.shared.SplitResult; public static String format(final String format, final Object... args) { final RegExp regex = RegExp.compile("%[az]"); final SplitResult split = regex.split(format); final StringBuffer msg = new StringBuffer(); for (int pos = 0; pos < split.length() - 1; ++pos) { msg.append(split.get(pos)); msg.append(args[pos].toString()); } msg.append(split.get(split.length() - 1)); return msg.toString(); } 

甚至更简单,不使用RegExp,只使用string:

 public static String format(final String format, final String... args) { String[] split = format.split("%s"); final StringBuffer msg = new StringBuffer(); for (int pos = 0; pos < split.length - 1; pos += 1) { msg.append(split[pos]); msg.append(args[pos]); } msg.append(split[split.length - 1]); return msg.toString(); } 

另一个使用JSNI和另一个post的 JavaScript格式函数的build议 :

 import com.google.gwt.core.client.JsArrayString; public abstract class StringFormatter { public static String format(final String format, final Object... args) { if (null == args || 0 == args.length) return format; JsArrayString array = newArray(); for (Object arg : args) { array.push(String.valueOf(arg)); // TODO: smarter conversion? } return nativeFormat(format, array); } private static native JsArrayString newArray()/*-{ return []; }-*/; private static native String nativeFormat(final String format, final JsArrayString args)/*-{ return format.replace(/{(\d+)}/g, function(match, number) { return typeof args[number] != 'undefined' ? args[number] : match; }); }-*/; } 

然后可以这样打电话:

 StringFormatter.format("Greetings {0}, it's {1} o'clock, which is a {2} statement", "Master", 8, false); 

…结果是

问候师傅,现在是八点,这是一个虚假的陈述

TODO评论有进一步改进的潜力,例如利用NumberFormat。 欢迎提出build议。

这个很快,而且忽略了不好的curl分隔的值:

 public static String format(final String format, final Object... args) { if (format == null || format.isEmpty()) return ""; // Approximate the result length: format string + 16 character args StringBuilder sb = new StringBuilder(format.length() + (args.length*16)); final char openDelim = '{'; final char closeDelim = '}'; int cur = 0; int len = format.length(); int open; int close; while (cur < len) { switch (open = format.indexOf(openDelim, cur)) { case -1: return sb.append(format.substring(cur, len)).toString(); default: sb.append(format.substring(cur, open)); switch (close = format.indexOf(closeDelim, open)) { case -1: return sb.append(format.substring(open)).toString(); default: String nStr = format.substring(open + 1, close); try { // Append the corresponding argument value sb.append(args[Integer.parseInt(nStr)]); } catch (Exception e) { // Append the curlies and the original delimited value sb.append(openDelim).append(nStr).append(closeDelim); } cur = close + 1; } } } return sb.toString(); } 

我并不热衷于滥用string操作来完成正则expression式的工作,但是基于bodrin的解决scheme,您可以编写代码:

 public static String format (String pattern, final Object ... args) { for (Object arg : args) { String part1 = pattern.substring(0,pattern.indexOf('{')); String part2 = pattern.substring(pattern.indexOf('}') + 1); pattern = part1 + arg + part2; } return pattern; } 

作为替代,你可以使用类NumberFormat :

 NumberFormat fmt = NumberFormat.getDecimalFormat(); double value = 12345.6789; String formatted = fmt.format(value); // Prints 1,2345.6789 in the default locale 

另一个非常简单的replace为java.text.MessageFormat.format():

 public static String format(final String format, final Object... args) { StringBuilder sb = new StringBuilder(); int cur = 0; int len = format.length(); while (cur < len) { int fi = format.indexOf('{', cur); if (fi != -1) { sb.append(format.substring(cur, fi)); int si = format.indexOf('}', fi); if (si != -1) { String nStr = format.substring(fi + 1, si); int i = Integer.parseInt(nStr); sb.append(args[i]); cur = si + 1; } else { sb.append(format.substring(fi)); break; } } else { sb.append(format.substring(cur, len)); break; } } return sb.toString(); } 

也许最简单的方式来做像String.format,可以做一个String.replace,例如;

而不是做String.format("Hello %s", "Daniel"); ==> "Hello %s".replace("%s", "Daniel")

都给了我们相同的结果,但只是第二种方式在GWT客户端工作

如上所述,有数字和date的GWT格式化程序: NumberFormatDateTimeFormat 。 不过,我需要知道String.format(...)情况的解决scheme。 我最终得到这个解决scheme,我不知道是否是错误的性能,但它是视觉上干净。 我很高兴听到有关它的任何评论,或其他解决scheme。

我的string格式化程序

 public class Strings { public static String format(final String format, final Object... args) { String retVal = format; for (final Object current : args) { retVal = retVal.replaceFirst("[%][s]", current.toString()); } return retVal; } } 

和JUTest如果想要重新使用这个:

 public class StringsTest { @Test public final void testFormat() { this.assertFormat("Some test here %s.", 54); this.assertFormat("Some test here %s and there %s, and test [%s]. sfsfs !!!", 54, 59, "HAHA"); } private void assertFormat(final String format, final Object... args) { Assert.assertEquals("Formatting is not working", String.format(format, args), Strings.format(format, args)); } }