Подтвердить что ты не робот

Что такое эквивалент Java sscanf для синтаксического анализа значений из строки с использованием известного шаблона?

Итак, я родом из C-фона (первоначально изначально, хотя я не использовал этот язык почти 5 лет), и я пытаюсь разобрать некоторые значения из строки в Java. В C я бы использовал sscanf. В Java люди сказали мне "использовать Scanner или StringTokenizer", но я не вижу, как их использовать для достижения моей цели.

Моя строка ввода выглядит как "17-MAR-11 15.52.25.000000000". В C я бы сделал что-то вроде:

sscanf(thestring, "%d-%s-%d %d.%d.%d.%d", day, month, year, hour, min, sec, fracpart);

Но в Java все, что я могу сделать, это такие вещи, как:

scanner.nextInt();

Это не позволяет мне проверять шаблон, а для "MAR" мне приходится делать такие вещи, как:

str.substring(3,6);

Ужасный! Наверняка есть лучший способ?

4b9b3361

Ответ 1

Проблема заключается в том, что Java не выводит параметры (или передает по ссылке) как C или С#.

Но есть лучший способ (и более твердый). Используйте регулярные выражения:

Pattern p = Pattern.compile("(\\d+)-(\\p{Alpha}+)-(\\d+) (\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)")
Matcher m = p.matcher("17-MAR-11 15.52.25.000000000");
day = m.group(1);
month= m.group(2);
....

Конечно, код C более краткий, но этот метод имеет одну прибыль: Шаблоны задают формат более точным, чем "% s" и "% d". Поэтому вы можете использовать \d {2}, чтобы указать, что этот день ДОЛЖЕН составлять ровно 2 цифры.

Ответ 2

Вот решение, использующее сканеры:

Scanner scanner = new Scanner("17-MAR-11 15.52.25.000000000");

Scanner dayScanner = new Scanner(scanner.next());
Scanner timeScanner = new Scanner(scanner.next());

dayScanner.useDelimiter("-");
System.out.println("day=" + dayScanner.nextInt());
System.out.println("month=" + dayScanner.next());
System.out.println("year=" + dayScanner.nextInt());

timeScanner.useDelimiter("\\.");
System.out.println("hour=" + timeScanner.nextInt());
System.out.println("min=" + timeScanner.nextInt());
System.out.println("sec=" + timeScanner.nextInt());
System.out.println("fracpart=" + timeScanner.nextInt());

Ответ 3

Ни один из этих примеров не был действительно удовлетворительным для меня, поэтому я сделал свою собственную утилиту java sscanf:

https://github.com/driedler/java-sscanf/tree/master/src/util/sscanf

Вот пример разбора шестнадцатеричной строки:

String buffer = "my hex string: DEADBEEF\n"
Object output[] = Sscanf.scan(buffer, "my hex string: %X\n", 1);

System.out.println("parse count: " + output.length);
System.out.println("hex str1: " + (Long)output[0]);

// Output:
// parse count: 1
// hex str1: 3735928559

Ответ 4

Для "17-MAR-11 15.52.25.000000000":

SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yy HH.mm.ss.SSS");

try 
{
    Date parsed = format.parse(dateString);
    System.out.println(parsed.toString());
}
catch (ParseException pe)
{
    System.out.println("ERROR: Cannot parse \"" + dateString + "\"");
}

Ответ 5

Это далеко не столь элегантное решение, как с помощью регулярного выражения, но должно работать.

public static void stringStuffThing(){
String x = "17-MAR-11 15.52.25.000000000";
String y[] = x.split(" ");

for(String s : y){
    System.out.println(s);
}
String date[] = y[0].split("-");
String values[] = y[1].split("\\.");

for(String s : date){
    System.out.println(s);
}
for(String s : values){
    System.out.println(s);
}

Ответ 6

Вы знакомы с концепцией регулярных выражений? Java предоставляет вам возможность использовать регулярное выражение с помощью класса Pattern. Проверьте это: http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html

Вы можете проверить свою строку следующим образом:

Matcher matcher = Pattern.match(yourString);
matcher.find();

а затем используйте методы, предоставленные Matcher, для управления найденной вами строкой или NOT.

Ответ 7

System.in.read() - это еще один вариант.