这也接受不正确的格式,但格式解析器显然太昂贵(即,工作量太大)-尽管这可能比正则表达式匹配更有效。我不能说这是否优雅-可能输入变化太复杂,无法采用流畅或光滑的方法。
我已经更改了我的第一个解决方案,它仅返回最少数量的参数,因为添加错误类型的参数可能会导致异常:您应该使用与转换代码匹配的类的参数。使用null会导致警告和丑陋的输出。
Pattern pat = Pattern.compile( "(?!<%)%" +
"(?:(\\d+)\\$)?" +
"([-#+ 0,(]|<)?" +
"\\d*" +
"(?:\\.\\d+)?" +
"(?:[bBhHsScCdoxXeEfgGaAtT]|" +
"[tT][HIklMSLNpzZsQBbhAaCYyjmdeRTrDFc])" );
Class<?> classOf( String conv ){
if( conv.startsWith( "t" ) ){
return Date.class;
}
switch( conv.charAt( 0 ) ){
case 'b':
return Boolean.class;
case 'h': case 'd': case 'o': case 'x':
return Integer.class;
case 's':
return String.class;
case 'c':
return Character.class;
case 'e': case 'f': case 'g': case 'a':
return Double.class;
default:
return Void.class;
}
}
List<Class<?>> count( String fmt ){
List<Class<?>> res = new ArrayList<>();
Matcher m = pat.matcher( fmt );
while( m.find() ){
if( m.group(1) != null ){
String dec = m.group(1);
int ref = Integer.parseInt( dec );
if( res.size() < ref ){
while( res.size() < ref - 1 ){
res.add( Void.class );
}
res.add( classOf( m.group(3).toLowerCase() )) ;
} else {
Class<?> clazz = classOf( m.group(3).toLowerCase() );
res.set( ref - 1, clazz );
}
} else if( m.group(2) != null && "<".equals( m.group(2) ) ){
} else {
res.add( classOf( m.group(3).toLowerCase() ));
}
}
return res;
}
测试使用
void demo( String... formats ){
for( String fmt: formats ){
List<Class<?>> res = count( fmt );
System.out.print( fmt + ": " + res.size() + ":" );
for( Class<?> clazz: res ){
System.out.print( " " + clazz.getSimpleName() );
}
System.out.println();
}
}
输出:
%d: 1: Integer
%1$d: 1: Integer
the %s jumped over the %s, %d times: 3: String String Integer
the %1$s jumped over the %1$s, %2$d%% %n: 2: String Integer
Duke's Birthday: %1$tm %1$te,%1$tY: 1: Date
Duke's Birthday: %1$tm %<te,%<tY: 1: Date
%4$s %3$s %2$s %1$s %4$s %3$s %2$s %1$s: 4: String String String String
%s %s %<s %<s: 2: String String
%s %s %s %s: 4: String String String String
%2$s %s %<s %s: 4: Void String String String
这是简单版本,只返回计数:
int count( String fmt ){
Matcher m = pat.matcher( fmt );
int np = 0;
int maxref = 0;
while( m.find() ){
if( m.group(1) != null ){
String dec = m.group(1);
int ref = Integer.parseInt( dec );
maxref = Math.max( ref, maxref );
} else if( m.group(2) != null && "<".equals( m.group(2) ) ){
} else {
np++;
}
}
return Math.max( np, maxref );
}
Pattern p = Pattern.compile("[^%]%([+-]?\\d*.?\\d*)?[sdf]"); Matcher m = p.matcher(input); int count = 0; while(m.find()) count++;
- DimaSystem.out.printf("%1$d %1$d %n",42);
)。此外,%n
不是变量的占位符,而是操作系统相关的换行符。 - Pshemo