Java Text splitten mit Tabs, Zeilen, Zeichen und Klammern.

snuff

Mitglied
Hallo zusammen.

Ich Suche nach einer Möglichkeit Zahlen, welche in einer .txt Datei gespeichert sind, auszulesen und in einem Double Array zu speichern.

Die Zahlen in der Textdatei können dabei auf unterschiedliche Art und Weise getrennt sein, z.B. durch Kommas, Lerschläge, Tabs, Zeilenschaltung, Strichpunkte und eckige Klammern. Hier einige Beispiele:
Code:
Sting text1 = "1, 2, 3, 4, 5, 6,80";
String text2 = "[1 2 3 4 5 6 80]";
String text3 = "[1,, 2 3       4   ,5;6;      80]";

In allen 3 Fällen wäre das gewünschte Erbegnis:
Code:
Double[] daten = {1, 2, 3, 4, 5, 6, 80}

Die Datei lese ich mit einem BufferedReader ein. Danach habe ich ein String welcher 1 zu 1 den Inhalt hat wie in der .txt Datei mit allen Tabs, Zeilen, Klammern, usw.
Beim aufsplitten mit der string.split(regex) funktion habe ich dabei so einige Probleme.

Leerschläge und Kommas zu trenne funktioniert problemlos mittels
Code:
String[] temp = text.split("[, ]+");


Wenn die Zahlen nun innerhalb einer Eckigen Klammer sind bekomme ich beim Ausführen eine PatternSyntaxException, da die Eckigen klammern ja eine bstimmte Bedeutung in der Regex Syntax haben. Also so etwas wie
Code:
String[] temp = text.split("[, ][]+");
funktioniert nicht. Daher die erste Frage: Wie entfernt man Eckige Klammern mit der Splitfunktion?

Das Zweite Problem entsteht bei tabs und mehreren Zeilen. Beim Ausführen von
Code:
String[] temp = text.split("\t");
String[] temp = text.split("\n");
erhalte ich immer ein leere Zelle im String Array wenn zwei Tabs bzw. zwei neue Zeilen hintereinander kommen (also eine Leere Zeile dazwischen). Wie behebe ich das?

Als letztes suche ich dann noch nach dem Argument für die Splitfunktion, welche möglichst alles gleichzeitig erledigt, sprich es wird nur eine Methode benötigt um alle Tabs, Klammern, usw zu entfernen.

Besten Dank und mfg
 
Würde das jetzt mal so machen:
Java:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
  
  public static void main(String... args) {
    String text1 = "1, 2, 3, 4, 5, 6,80";
    String text2 = "[1 2 3 4 5 6 80]";
    String text3 = "[1,, 2 3       4   ,5;6;      80]";
    for (String s : Arrays.asList(text1, text2, text3)) {
      System.out.println(Arrays.toString(parse(s)));
    }
  }
  
  private static final Pattern NUMBER_PATTERN = Pattern.compile("\\d+");
  
  public static Double[] parse(String s) {
    List<Double> doubles = new ArrayList<>();
    Matcher matcher = NUMBER_PATTERN.matcher(s);
    while (matcher.find()) {
      doubles.add(Double.valueOf(matcher.group()));
    }
    return doubles.toArray(new Double[doubles.size()]);
  }
}
 
Hallo
Danke für deine Antwort. Beim implementieren deines Codes stosse ich bei folgender Stelle auf ein Problem:
Code:
List<Double> doubles = new ArrayList<>();
Ergibt bei mir die Fehlermeldung: "The type List is not generic; it cannot be parameterized with arguments <Double>"
Da ich noch nie mit Array-Listen in Java gearbeitet habe weiss ich nicht wie ich den Fehler beheben kann.

Des Weiteren habe ich noch mit der Split-Funktion ein wenig rumprobiert. Mit
Code:
String[] temp = text.split("\\D+");
konnte ich bisher alle Textdateien korrekt einlesen. Allerdings habe ich hier das Problem, dass das erste Element im String Array immer "empty" ist. Beim casten via
Code:
Double[] data = new Double[temp.length];
for(int i = 0; i < temp.length; i++){
    data[i] = Double.parseDouble(temp[i]);
}
Erhalte ich dann die entsprechende Exception dass das Array leer ist.
Gibt man das String Array in der Konsole aus dann sieht man, dass es stets nur das erste Element ist welches nicht vorhanden ist.
Hier ist die Methode, evt. findet jemand den Fehler.
Code:
public Double[] convertStringToArray(String text){
        String[] temp = text.split("\\D+");
        Double[] data = new Double[temp.length];
        for(int i = 0; i < data.length; i++){
            try {
                data[i] =  Double.parseDouble(temp[i]);
            } catch (Exception e) {
                data[i] = -1.0;
            }
        }
        return data;
    }
Beim nutzen dieser Methode ist das erste Element jedes Arrays stets -1.0 (Den Wert den ich bei der Exception zuweise)

Eine Überprüfung des Array in Form von
Code:
if(temp[i] != null){
    //hier die try catch Abfrage
}
funktioniert ebenfalls nicht. Das erste Element bleibt beim Wert -1.0.
 
Code:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
(1 zu 1 vom Beispiel übernommen)

jre1.8.0_111 (Bin mir nicht sicher ob ich hier das richtige rausgesucht habe)
 
Java:
/**
* @author Jan Müller
*/

package test;

import java.util.ArrayList;

public class Blub {
    public static void main(String[] args) {
        String text3 = "[1,, 2 3       4   ,5;6;      80]";

        ArrayList<Double> doubleArray = new ArrayList<Double>();
        String[] stringArray = text3.split("\\D");
      
        int i = 0;
        while (i < stringArray.length) {
            try {
                doubleArray.add(Double.parseDouble(stringArray[i++]));
            } catch (NumberFormatException e) {

            }
        }
        System.out.println(doubleArray); // --> [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 80.0]
    }
}

Falls möglicherweise muss der RegExp noch angepasst werden falls du echte doubles einlesen willst. Bis jetzt wird bei jedem nonDigit char getrennt. Und falls wirklich ein double[] gewünscht ist was weniger funktionen bietet als ein ArrayList dann gibt es die Funktion toArray()
 

Zurück
Oben