Java Text Dateien Parsen

Timmey92

Commodore
Registriert
Okt. 2008
Beiträge
4.571
Hallo,

arbeite grade an einem kleinen Programm um Text Dateien zu parsen.
Mein Code klappt mehr schlecht als recht.
Würden sich regular Expressions besser eigenen um das zu machen?
Wenn ja: wie geht das?
Ansonsten Ansätze, Tipps?

Muster:
Code:
[1]
FZ1         = 
FZ2         =  Text1?
FZ3         = 
Min         =  0
Max         = 1000
Antwort_1   = 1 Antwort1
Antwort_2   = 0 Antwort2
Antwort_3   = 0 Antwort3
Antwort_4   = 0 Antwort4

Mal sind leerzeichen zwischen key, gleichheitszeichen und dem wert, mal aber auch nicht, wie z.b. so

Code:
[1]
FZ1=
FZ2=Text2?
FZ3=
Min=0
Max=500
Antwort_1=1Anwort1
Antwort_2=0Antwort2
Antwort_3=0Antwort3
Antwort_4=0Antwort4

Code:
public class ParseQuestions {
	
	static Frage currentQuestion = null;
	
	/**
	 * @param args
	 * @throws FileNotFoundException 
	 */
	public static void main(String[] args) throws FileNotFoundException {
		try {
			System.out.println("Datei:");
			
			Scanner in = new Scanner(System.in);

			String fileName = in.nextLine();
			File file = new File(fileName);
		
		if(!file.exists())
			file.createNewFile();
		System.out.println(file.getAbsolutePath());
		
		BufferedReader br = new BufferedReader(new FileReader(file));
		
		String line = "";
		String bigline = "";
		//datei Zeilenweise durchlesen
		
			
		int i = 0;
		int questionno = 0;
			while((bigline = br.readLine()) != null)
			{
				i++;
				//System.out.println("lese Zeile:"+i);
				//we are at a new question
				if(bigline.contains("["))
				{
					if(bigline.contains("Thema"))
						continue;
					
					currentQuestion = new Frage();	
					questionno++;
					while((line = br.readLine()) != null)
					{
						i++;
						//System.out.println("lese Zeile: "+i);
						if(line.contains("FZ1"))
						{
							currentQuestion.FZ1 = line.replace("FZ1=", "");
						}
						else if(line.contains("FZ2"))
						{
							currentQuestion.FZ2 = line.replace("FZ2=", "");
							
						}
						else if(line.contains("FZ3"))
						{
							currentQuestion.FZ3 = line.replace("FZ3=f", "");
							
						}
						else if(line.contains("Antwort_1"))
						{
							if(line.contains("=1"))
								currentQuestion.correctanswer=1;
							
							currentQuestion.answers[0]=line.substring(11);
							
						}
						else if(line.contains("Antwort_2"))
						{
							if(line.contains("=1"))
								currentQuestion.correctanswer=2;
							
							currentQuestion.answers[1]=line.substring(13);
							
						}
						else if(line.contains("Antwort_3"))
						{
							if(line.contains("=1"))
								currentQuestion.correctanswer=3;
							
							currentQuestion.answers[2]=line.substring(13);
						}
						else if(line.contains("Antwort_4"))
						{
							if(line.contains("=1"))
								currentQuestion.correctanswer=4;
							
							currentQuestion.answers[3]=line.substring(13);
							Frage.addQuestion(currentQuestion);							
							System.out.println("füge Frage hinzu:"+questionno);
							break;
							
						}											
					}
				}
				
				
				
			}
			
			
			
			br.close();
			
		} catch (Exception e) {
			// TODO Auto-generated catch block			
			e.printStackTrace();
		}
		Frage.writeQuestions();
		System.out.println("Fertig!");
		
		
		
	}

}
 
Das ist ja eine relativ einfache Struktur. Ich schlage vor schau dir mal
String.split an, um die Strings vor und hinter dem "=" zu isolieren
trim(), um störende Leerzeichen zu entfernen.
mit toUpperCase ist es sogar egal, ob der Key groß oder klein geschrieben ist.
Code:
    public static void main(String[] args) {

        String s = "Key = Value";  // der string wird in ein Array zerlegt
        String[] sa;
        
        sa = s.split("=");  // sa[0] enthält den text links vom "=" sa[1] den rechts
        // komplizierter wird es, wenn das "=" auch im Value-Teil vorkommen soll
        
        System.out.println(sa[0].trim());
        System.out.println(sa[1].trim());

        System.out.println(sa[0].trim().toUpperCase());
        System.out.println(sa[1].trim());
        
    }
 
ahh okay, @DjNDB: nein, weil ich die Daten schon in dieser Struktur habe, aber sie nicht für mein Programm verwenden kann.

@R0b0t: genau das wollte ich wissen. ich bau das gleich mal ein, mal gucken wie das so geht :)
 
BloodHunter2k8 schrieb:
ahh okay, @DjNDB: nein, weil ich die Daten schon in dieser Struktur habe, aber sie nicht für mein Programm verwenden kann.

Mit Properties solltest du die so 1:1 einlesen können.
 
Statt String.split() kannst du auch mit StringTokenizer arbeiten. Der bricht dir die Strings an den Stellen auseinander, die du selbst definieren kannst.

Code:
Code:
import java.util.StringTokenizer;

public class TestDriver {

	public static void main(String[] args) {
		String beliebigerString = "[1]\n" +
					  "a = 10\n" +
					  "b= 20 \n" +
					  "c =30\n\n";
		
		StringTokenizer st = new StringTokenizer(beliebigerString);

		while (st.hasMoreTokens())
			System.out.println(st.nextToken("=\n").trim());
	}

}
Ausgabe:
Code:
[1]
a
10
b
20
c
30

Hier bricht er immer an dem "=" und dem Zeilenumbruch "\n".
 
danke.

trim hat mir noch gefehlt gehabt :)
und split macht die ganze sache einfach.

die anderen lösungen schau ich mir aber auch noch an.
 
@e-Laurin
Der StringTokenizer ist deprecated und sollte nicht mehr verwendet werden! Die split()-Methode von String ist in jedem Falle vorzuziehen!
 
Ok, nicht deprecated, aber es wird davon abgeraten, die Klasse zu benutzen.

Zitat Java-API:
"StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead."
 
Zurück
Oben