Quel Est L'équivalent Java de sscanf pour analyser les valeurs d'une chaîne en utilisant un motif connu?

donc je viens d'un arrière-plan en C (à l'origine, même si je n'ai pas utilisé ce langage depuis près de 5 ans) et j'essaie d'analyser certaines valeurs à partir d'une chaîne en Java. En C, j'utiliserais sscanf. En Java, les gens m'ont dit "Utilisez Scanner, ou StringTokenizer", mais je ne vois pas comment les utiliser pour atteindre mon but.

ma chaîne de caractères ressemble à "17-MAR-11 15.52.25.00000000000". En C je ferais quelque chose comme:

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

mais à Java, tout ce que je peux faire c'est comme:

scanner.nextInt();

cela ne me permet pas de vérifier le modèle, et pour " MAR " je finis par avoir à faire des choses comme:

str.substring(3,6);

Horrible!!! Il y a sûrement un meilleur moyen?

26
demandé sur riffraff 2011-12-08 15:10:01

7 réponses

le problème est que Java n'a pas perdu les paramètres (ou en passant par référence) en tant que c ou c#.

mais il y a une meilleure façon (et plus solide). Utiliser des expressions régulières:

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);
....

bien sûr c code est plus concis, mais cette technique a un profit: Patterns spécifie un format plus précis que' %s 'et'%d'. Vous pouvez donc utiliser \d{2} pour spécifier que le jour doit être composé d'exactement 2 chiffres.

38
répondu korifey 2011-12-08 11:21:53

Voici une solution utilisant des scanners:

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());
21
répondu dsboger 2011-12-08 12:23:33

aucun de ces exemples n'était vraiment satisfaisant pour moi donc j'ai fait mon propre utilitaire java sscanf:

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

Voici un exemple de l'analyse d'une chaîne hexadécimale:

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
10
répondu user1495323 2013-03-07 07:02:19

For "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 + "\"");
}
3
répondu DefenestrationDay 2012-04-17 23:01:44

c'est loin d'être la solution la plus élégante que l'on puisse obtenir avec l'utilisation de regex, mais devrait fonctionner.

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);
}
2
répondu Zavior 2011-12-08 11:30:07

connaissez-vous le concept d'expressions régulières? Java vous offre la possibilité d'utiliser regex en utilisant la classe Pattern. Vérifier celui-ci dehors: http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html

Vous pouvez tester votre Chaîne comme ça:

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

et ensuite utiliser les méthodes fournies par Matcher pour manipuler la chaîne que vous avez trouvé ou non.

0
répondu Nikola Yovchev 2014-06-25 02:38:22

Système.in.read () est une autre option.

-3
répondu radbanr 2013-12-22 10:04:54