我想分析最终传递给
的模式String.format(String pattern, Object... args)
让我们考虑一下模式
"Integer is %d, String is %s"
有没有办法可以解析这种模式来确定
显然我可以使用正则表达式执行此操作,但是当在模式中指定索引等时,这会变得更加困难。例如,让我们考虑另一种模式
"String is %2$s, Integer is %1$d"
这里arg1在arg0之前指定,但是这两个模式对于相同的参数具有相同的格式化。
我真的很想使用核心java类来解析模式并对其进行分析,但似乎所有方法都是私有的。在幕后,String.format()
使用Formatter。
最终,我试图编写一个测试用例来验证我的各种语言翻译文件并发现冲突(例如,一种语言指定日期格式,另一种语言指定同一参数的数字格式)。
答案 0 :(得分:0)
对于开源项目,您可以将自己的TestFormatter基于Formatter (source)的源。然后,在format
()方法的切换情况下,请记住参数类型,如下所示:
代码:
argument = args[argumentIndex];
switch (conversion) {
case 'b':
argumentHashMap.put(new Integer(argumentIndex), Boolean.class);
booleanFormat(argument, flags, width, precision, origConversion);
break;
case 's':
argumentHashMap.put(new Integer(argumentIndex), String.class);
stringFormat(argument, flags, width, precision, origConversion);
break;
case 'd':
argumentHashMap.put(new Integer(argumentIndex), Double.class);
decimalConversion(argument, flags, width, precision, origConversion);
break;
...
我添加了argumentHashMap
行。
答案 1 :(得分:0)
我最终通过借用java源代码中的正则表达式来解决我的问题。
public class MyTest {
static class PlaceHolder {
int index;
String flags;
Integer width;
Integer precision;
String type;
String conversion;
@Override
public String toString() {
return String.format("PlaceHolder[index=%s, conversion=%s, flags=%s, width=%s, precision=%s, type=%s]",
index, conversion, flags, width, precision, type);
}
}
public List<PlaceHolder> getPlaceholders(String pattern) {
// %[argument_index$][flags][width][.precision][t]conversion
Pattern regex = Pattern.compile("%((\\d+)\\$)?([-#+ 0,(\\<]*)?(\\d+)?(\\.(\\d+))?([tT])?([a-zA-Z%])");
int nextImplicitIndex = 1;
Matcher matcher = regex.matcher(pattern);
List<PlaceHolder> placeholders = new ArrayList<PlaceHolder>();
while (matcher.find()) {
String sIndex = matcher.group(2);
int index = sIndex == null ? nextImplicitIndex++ : Integer.parseInt(sIndex);
String flags = matcher.group(3);
String sWidth = matcher.group(4);
String sPrecision = matcher.group(6);
String type = matcher.group(7);
String conversion = matcher.group(8);
PlaceHolder placeholder = new PlaceHolder();
placeholder.index = index;
placeholder.flags = flags;
placeholder.width = sWidth == null ? null : new Integer(sWidth);
placeholder.precision = sPrecision == null ? null : new Integer(sPrecision);
placeholder.type = type;
placeholder.conversion = conversion;
placeholders.add(placeholder);
}
return placeholders;
}
@Test
public void testGetPlaceholders() {
System.out.println(getPlaceholders("Integer is %d, String is %s"));
System.out.println(getPlaceholders("String is %2$s, Integer is %1$d"));
System.out.println(getPlaceholders("%,6.2f"));
System.out.println(getPlaceholders("Today is %tB %te, %tY %n"));
}
}
测试输出以下内容:
[PlaceHolder[index=1, conversion=d, flags=, width=null, precision=null, type=null], PlaceHolder[index=2, conversion=s, flags=, width=null, precision=null, type=null]]
[PlaceHolder[index=2, conversion=s, flags=, width=null, precision=null, type=null], PlaceHolder[index=1, conversion=d, flags=, width=null, precision=null, type=null]]
[PlaceHolder[index=1, conversion=f, flags=,, width=6, precision=2, type=null]]
[PlaceHolder[index=1, conversion=B, flags=, width=null, precision=null, type=t], PlaceHolder[index=2, conversion=e, flags=, width=null, precision=null, type=t], PlaceHolder[index=3, conversion=Y, flags=, width=null, precision=null, type=t], PlaceHolder[index=4, conversion=n, flags=, width=null, precision=null, type=null]]