Suche nach Trennoperatoren '|'

Edelfalke

Mitglied
Hallo,
ich bin ein Neuling was Java angeht und benötige eure Hilfe.
Ich versuche mittlerweile seit knapp einem Monat folgende Funktion zu realisieren, und brache jetzt eure Hilfe.
Es sind 2 textfiles einzulesen (habe mich da für RandomAccessFile entschieden, da die Files recht groß sind und es mit nem Buffer echt problematisch ist),
in diesen Files soll ich nun nach bestimmten Inhalten suchen und bei einem Fund aus der jeweiligen Zeile einige der vorhandenen wörter, sätze bzw werte auslesen und diese in einer neuen Datei strukturiert ablegen.

Die struktur der eingabefiles sieht in etwa so aus:

0|A|BBBBB|CCCCC|DDDDD|EEEEE|6|||1A|F.........
es ist immer unterschiedlich, das einzige was gleich bleibt ist die Anzahl der '|', dh. wenn ich zum fünften '|' springe, finde ich dahinter immer "EEEEE" und so weiter.

Das Ausgabefile soll in etwa folgende struktur haben:

A CCCCC F 2 6
dh. in einer anderen Reihenfolge und mit einem Leerzeichen getrennt.


Mein Hauptproblem liegt darin eine effektive Suche zu realisieren, die '|' abzuzählen und die werte dahinter bzw davor auszulesen..


Die syntax müsste so in etwa aussehen:
suche nach 0|*, springe 3 '|' weiter, kopiere was dahinter steht (am besten in eine variable oder Array), springe zwei '|' weiter kopiere was dahinter steht, springe drei '|' weiter kopiere was dahinter steht (hier evtl. noch eine wandlung von hex auf dezimal :)).


Ich bin für jede Hilfe dankbar, da ich mit meinem bißchen Java echt am ende bin.

Gruß Alex
 
Vielleicht hilft das ein bisschen:

Du kriegst ja aus deiner File denke ich mal jede Zeile der File als String übergeben. dann kannt du suchen, ersetzten etc. auf diesem String.

Ist eine Zeichensequenz in einem String enthalten, dann mache etwas:
if (value.contains("n|")){
}

Die Position (Die Startposition des ersten zeichens) einer zeichensequenz innerhalb eines Strings bekommst du mit:
int index=value.indexOf("n|");

Einen Teilstring, auch substring genannt, von einem Index bis zum ende des strings bekommst du mit:
String newValue=value.substring(index);

Einen Teilstring, auch substring genannt, von einem Index bis zu einem anderen index des Strings bekommst du mit:
String newValue=value.substring(index1,index2 );


Du kannst natürlich bis zum 5. "|" springen, indem du in einer schleife so oft einen Substring nimmst, bis du beim fünften "|" bist...

zu deinen problem nur grob skizziert (syntax stimmt bestimmt nicht ;) ):

gegeben: String 0|A|BBBBB|CCCCC|DDDDD|EEEEE|6|||1A|F.........
aus deiner File.

suche nach 0|*, :
if value.contains( "0|"){
int index = value.indexOf("0|");
}

springe 3 '|' weiter:
value = value.substring(index+2) //du nimmst den substring nach demersten "0|" bis zum ende
if value.contains( "|"){
int index = value.indexOf("|");
}

value = value.substring(index+1) //du nimmst den substring nach demersten "|" bis zum ende --> A|BBBBB|CCCCC|DDDDD|EEEEE|6|||1A|F.........


if value.contains( "|"){
int index = value.indexOf("|");
}
value = value.substring(index+1) //du nimmst den substring nach demersten "|" bis zum ende --> BBBBB|CCCCC|DDDDD|EEEEE|6|||1A|F.........


if value.contains( "|"){
int index = value.indexOf("|");
}
value = value.substring(index+1) //du nimmst den substring nach demersten "|" bis zum ende --> CCCCC|DDDDD|EEEEE|6|||1A|F.........


kopiere was dahinter steht (am besten in eine variable oder Array):
if value.contains( "|"){
int index = value.indexOf("|");
}
String NewValue = value.substring(0, index-1) //du nimmst von 0 bis zum "|", und noch -1 denke ich um davor zu enden (ausprobieren) NewValue = CCCCC


springe zwei '|' weiter kopiere was dahinter steht, springe drei '|' weiter kopiere was dahinter steht...

siehe oben...

(hier evtl. noch eine wandlung von hex auf dezimal ).
--> keine ahnung garde. ist aber nicht schwer
 
nochwas zum files einlesen, ich mache es meistens so:



Ich habe eine Klasse zum laden, die verwende ich immer mal wieder. Die hat zwei konstruktoren, entweder gibst du path und filename an, oder du öffnest nen fileChooser:

(der lädt beim file chooser glaub im moment nu *.txt files, kannst du aber einfach ändern indem du den suffix änderst oder weitere angibst..)


import java.io.*;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;

public class LoadSettings {

private String dataDir;
private String dataName;

BufferedReader in;

public LoadSomething(String stringDataDir, String stringDataName) {
dataDir = stringDataDir;
dataName= stringDataName;
try {
in = new BufferedReader(new InputStreamReader(new FileInputStream(dataDir+dataName)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}

public LoadSomething(){
JFileChooser d = new JFileChooser();
d.setFileFilter( new FileFilter()
{
public boolean accept(File f){
return f.isDirectory() || f.getName().toLowerCase().endsWith(".txt");
}
public String getDescription(){
return "*.txt";
}
} );
d.showOpenDialog( null );
File file = d.getSelectedFile();

try {
in = new BufferedReader(new InputStreamReader(new FileInputStream(file.getPath())));
} catch (FileNotFoundException e) {
e.printStackTrace();
}


}


public void close(){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}

public String read(){
try {
String s = in.readLine();
return s;
}
catch (IOException ex) {
ex.printStackTrace();
}
return "";
}
}




die verwende ich dann in einer anderen klasse etwa so:

// erzeuge neues Objekt der LoadSomething Klasse
LoadSomething load = new LoadSomething();

// hier schreib ich die datei zeilenweise rein
String line="";

// und nun zeile für zeile die datei auslesen und mit ihr arbeiten
while (!line.equals("")) //hier muss man vllt auch mit while line != null oder so arbeiten
{
line=load.read();

// und nu mit der line arbeiten
if (line.contains(......

}
 
Zuletzt bearbeitet:
WOW,
mit einer solch schnellen Antwort habe ich gar nicht gerechnet,
und vor allem nicht mit einer so umfangreichen.
Danke schonmal für die Ansätze, werde ich gleich ausprobieren!!


Gruß Alex
 
Hallo,
Das Ausgabefile soll in etwa folgende struktur haben:

A CCCCC F 2 6
dh. in einer anderen Reihenfolge und mit einem Leerzeichen getrennt.



Dazu nochwas ganz kurz, hab ich eben vergessen:

String a1 = "A";
String a2 = "CCCCCC";
String a3 = "2";
//konkatenieren von Strings:
String toWrite =a1 + " " + a1 + " "+a3 ; // --> toWrite = "A CCCCCC 2"

//erzeugen eines speicher-objektes
Save s = new Save();
//anhängen einer neuen Zeile
s.append (toWrite);
s.append (nochEinString)

//datei schließen
s.close();

Die klasse Save ist angehängt (als txt, musst du in .java umbenennen), aber geht nur als file chooser glaub ich.... teste einfach mal beizeiten.

Lg, und viel spass beim testen.

Ps: ich antworte grade auch nur so schnell, weil ich selbst auf eine Antwort warte und nicht weiter komm :suchen:
 

Anhänge

Und wieder ein dikkes Dankeschön an euch beide!
@kaffee_trinken
das Problem ist eben, dass ich nicht weiss was hinter A , CCCC etc steckt, diese Werte muss ich erst auslesen, das mit dem Speichern klappt auch mit RandomAccessFile relativ gut. Leider bekomm ich nicht den gewünschten Effekt bei deinem obigen Beispiel mit dem suchalgorythmus. Da steh aber ich selbst warscheinlich auf dem Schlauch.
Es liegt warscheinlich daran, dass ich den RandomAccessFile nutze und bei dir der BufferedReader benutzt wird, muss ich nochmal genauer anschauen.
@Matthias Reitinger
Danke, sieht höchst kompliziert aus, zumindest für einen Anfänger mit sehr schwachen Englisch. Wäre nett wenn du, wenn Zeit da ist, mal ein kleines Beispiel posten würdest.



PS. wenn ich schonmal dabei bin, hat hier evtl. ein vernünftiges howto, wie man ein logfile erstellen kann?

Gruß Alex
 
Zuletzt bearbeitet:
Und wieder ein dikkes Dankeschön an euch beide!
das Problem ist eben, dass ich nicht weiss was hinter A , CCCC etc steckt, diese Werte muss ich erst auslesen, das mit dem Speichern klappt auch mit RandomAccessFile relativ gut. Leider bekomm ich nicht den gewünschten Effekt bei deinem obigen Beispiel mit dem suchalgorythmus. Da steh aber ich selbst warscheinlich auf dem Schlauch.
Es liegt warscheinlich daran, dass ich den RandomAccessFile nutze und bei dir der BufferedReader benutzt wird, muss ich nochmal genauer anschauen

spezifizier mir doch nochmal ganz genau wie deine daten aussehen, also was hast du ganz konkret für einen Wert den du parsen willst. Und ist dieses zu parsende in einer Zeile, oder manchmal auch zeilenübergreifend?

Dazu noch kurz die Information, ob du in der Lage bist, die Daten zeilenweise aus der Datei in einen String hinein auszulesen. Das von mir beschriebene verfahren klappt bestimmt, solange du etwas festes hast, nachdem du suchen kannst (z. bsp. der "|") und du nen string hast... dann sind such-ersetz-finde operationen leicht drauf anzuwenden

Und häng mir doch mal kurz, als datei, falls nicht zu groß, eine solche datei zum einlesen an. am besten auchnoch deinen bisherigen code mit dem du das zeugs einließt. Du kannst mir aber auch direkt per renewor (a t ) gmail . com mailen.

Lg, rené
 
Danke nochmal für die Info.
Leider kann ich die Daten nicht herausgeben, da diese einer Geheimhaltung unterliegen.
Das mit dem Zeilenweise lesen, stimmt. Ich hatte vorher zwar zeilenweise eingelesen (mit readLine()), der Dateiinhalt lag aber als eine elend lange Zeile vor. Hab das jetzt soweit hingebogen, dass es schonmal teilweise funktioniert ;).
Die Syntax werde ich später hier reinschreiben. Jetzt ist erstmal Feierabend für heute :)

Vielen Dank für die Tips und Hilfestellungen, ich werde mich hier noch melden.

Schönen Feiertag noch an alle ;-)

Gruß Alex
 
Hallo Edelfalke,

hab mir jetzt nicht den gesamten Thread durchgelesen, aber anstatt die Lesereihenfolge der Ausgabereihenfolge anzupassen ...

suche nach 0|*, springe 3 '|' weiter, kopiere was dahinter steht (am besten in eine variable oder Array), springe zwei '|' weiter kopiere was dahinter steht, springe drei '|' weiter kopiere was dahinter steht (hier evtl. noch eine wandlung von hex auf dezimal ).

...

würde ich eher jeden Satz in ein kleines Model laden, welches halt soviele String-Variablen besitzt wie du benötigst (String part1, part2, part3...) und eben konsequent vom ersten "|" bis zum letzten "|" durchhüpfen und die Variablen befüllen.

Für die Ausgabe kannst du die geladenen Attribute dann anordnen wie du willst:
z.B. <part3> <part1> <part8> etc.

Gruß,
gring0
 
Zurück