2016-06-30 10 views
0

Ich bin ziemlich neu zu analysieren Textdateien mit Java. Meine Aufgabe ist es, ich eine Textdatei haben, die Strings und Double-Werte wie folgt enthält (Beispiel):Parsen von Strings und Doppelvektoren mit Scanner?

Wort 0,6478 1,74837 -0,2734 3.3475nextword 4,94756 -0,46372 3,29384 0.36475thirdword 5,92836 (...)

(und so weiter)

so enthält die Datei Wörter gefolgt von einer konsistenten Anzahl von lets sagen n numerische Werte, die in irgendeiner Weise mit dem Wort verbunden sind sie folgen. Was ich am Ende möchte, ist eine Reihe von Strings, die alle Wörter aus den Dateien und für jedes Wort den zugehörigen Vektor von n Doubles enthalten.

Meine erste Idee war es, den java.util.Scanner zu verwenden, aber soweit ich weiß, liest es nur durch Leerzeichen getrennte Objekte und wie Sie aus meinem Beispiel sehen können, gibt es keine Leerzeichen zwischen der letzten Nummer einer Gruppe und der nächstes Wort.

So gibt es eine einfache Möglichkeit, dies zu beheben, während Sie den Scanner oder eine noch einfachere mit einem anderen Parsing-Tool verwenden?

Ich bin dankbar für alle Tipps

UPDATE:

Ich habe ein anderes Problem. Meine Eingabedatei enthält exponentielle Zahlen wie: -2.1961d-05 Welche liest mein Scanner in die Nummer: -2.1961 und das Wort: e-05

gibt es sogar eine Chance, diese Art von Zahlen zu lösen?

+1

Ein anderes Problem verdient eine andere Frage. Hinweis: mehr Leute beobachten * neue * Fragenwarteschlange als bearbeitete (* aktive *) Fragenwarteschlange, so dass das Posten einer neuen Frage auch Ihre Chancen erhöht, eine Antwort zu erhalten. Wie auch immer, ich habe meine Antwort aktualisiert, um den Fall zu beschreiben, den Sie in Ihrer Bearbeitung beschrieben haben. – Pshemo

Antwort

0

Ja, standardmäßig verwendet der Scanner nur Leerzeichen (einschließlich Tabulatoren und Zeilentrennzeichen) als Trennzeichen. Aber wenn Sie sind vertraut mit regex (reguläre Ausdrücke) können Sie Ihre eigene Trennzeichen festlegen:

  • Whitespaces \s

oder Orte, die

haben
  • Ziffer vor (?<=\d)
  • und haben Sie keine Ziffer nach (?!\d)
  • ausschließlich Fall, wo nach Ziffer ist Punkt . (weil 12.34a nur 34a sollte getrennt werden) (?![.]).

(Ich habe hier positive und negative Look-Ahead-Mechanismus von Regex verwendet.Mehr Infos unter: http://www.regular-expressions.info/lookaround.html)

So können Sie Ihren Scanner einrichten wie:

Scanner sc = new Scanner(yourData); 
sc.useLocale(Locale.ENGLISH);//some locales use 12,34 for double, English ensures 12.34 format 
sc.useDelimiter("\\s|(?<=\\d)(?!\\d)(?![.])"); 

RE UPDATE:

sc.useDelimiter("\\s|(?<=\\d)(?!\\d)(?![.]|[eE]-?\\d+)"); 
0

Eine Möglichkeit (ohne Scanner) ist jede Zeile tokenise mit einem einfachen Regex und dann jedes Token analysieren:

String line = "word 0.6478 1.74837 -0.2734 3.3475nextword 4.94756 -0.46372 3.29384 0.36475thirdword 5.92836"; 
String nonNumeric = "[^\\d.-]"; 
//alternative: nonNumeric="[a-zA-Z\\s]" 
List<Double> doubles = Arrays 
    .asList(line.split(nonNumeric)) 
    .stream() 
    .filter(s -> !s.isEmpty()) 
    .map(s -> Double.parseDouble(s)) 
    .collect(Collectors.toList()); 
System.out.println(doubles); 
[0.6478, 1.74837, -0.2734, 3.3475, 4.94756, -0.46372, 3.29384, 0.36475, 5.92836]