2019年的答案:Java的Scanner可以灵活地读取各种格式。但是,如果您的格式只包含简单的{%d, %f, %s}字段,则可以使用这个小类(约90行)轻松扫描。
import java.util.ArrayList;
public class CFormat {
private static boolean accept(char t, char c, int i) {
if (t == 'd')
return "0123456789".indexOf(c) >= 0 || i == 0 && c == '-';
else if (t == 'f')
return "-0123456789.+Ee".indexOf(c) >= 0;
else if (t == 's')
return Character.isLetterOrDigit(c);
throw new RuntimeException("Unknown format code: " + t);
}
public static String printf(String fmt, Object... args) {
int a = 0;
StringBuilder sb = new StringBuilder();
int n = fmt.length();
for (int i = 0; i < n; i++) {
char c = fmt.charAt(i);
if (c == '%') {
char t = fmt.charAt(++i);
if (t == 'd')
sb.append(((Number) args[a++]).intValue());
else if (t == 'f')
sb.append(((Number) args[a++]).doubleValue());
else if (t == 's')
sb.append(args[a++]);
else if (t == '%')
sb.append(t);
else
throw new RuntimeException("Unknown format code: " + t);
} else
sb.append(c);
}
return sb.toString();
}
public static Object[] scanf(String fmt, String str) {
ArrayList ans = new ArrayList();
int s = 0;
int ns = str.length();
int n = fmt.length();
for (int i = 0; i < n; i++) {
char c = fmt.charAt(i);
if (c == '%') {
char t = fmt.charAt(++i);
if (t=='%')
c=t;
else {
int s0 = s;
while ((s == s0 || s < ns) && accept(t, str.charAt(s), s - s0))
s++;
String sub = str.substring(s0, s);
if (t == 'd')
ans.add(Integer.parseInt(sub));
else if (t == 'f')
ans.add(Double.parseDouble(sub));
else
ans.add(sub);
continue;
}
}
if (str.charAt(s++) != c)
throw new RuntimeException();
}
if (s < ns)
throw new RuntimeException("Unmatched characters at end of string");
return ans.toArray();
}
}
例如,可以像这样处理OP的情况:
// Example of "CFormat.scanf"
String str = "17-MAR-11 15.52.25.000000000";
Object[] a = CFormat.scanf("%d-%s-%d %d.%d.%f", str);
// Pick out scanned fields
int day = (Integer) a[0];
String month = (String) a[1];
int year = (Integer) a[2];
int hour = (Integer) a[3];
int min = (Integer) a[4];
double sec = (Double) a[5];
// Example of "CFormat.printf"
System.out.println(CFormat.printf("Got day=%d month=%s hour=%d min=%d sec=%f\n", day, month, year, hour, min, sec));
strptime
等效的选项,而不是scanf
。 - riffraff