String durchsuchen

Hallo,

ich möchte einen String auslesen und gewissen Teile rausziehen. Der String sieht etwa so aus: „PKF1234-APQ9283-RSZ095476383“. Die ersten drei Buchstaben dienen als Feldbezeichnung, die Zahlen dahinter bis zum Bindestrich sind der Inhalt. Diesen Inhalt möchte ich jeweils auslesen und in einen neuen String mit dem Namen der Feldbezeichnung kopieren. Abgeschlossen wird das ganze durch einen Back-Slash. Mit meinen schlechten und alten C++ Kenntnissen komm ich nicht weiter, da ich den String nicht wie einen Array mit einer for-Schleife durchsuchen kann. Kann jemand helfen?

Danke im voraus
Thomas

Hallo Thomas,

Prinzipiell kannst du den String schon mit einer Schleife untersuchen, die Methode length() gibt dir die Länge und charAt() das Zeichen an einer bestimmten Stelle.

Allerdings würde ich das nicht selber ausprogrammieren. Für einfachere Parse-Aufgaben reicht ein Regular Expressions-Library (z. B.: http://www.javaregex.com/). Für komplexere Dinge kann man einen Parser-Generator (z. B. JavaCC, http://www.google.at/search?q=javacc&ie=UTF-8&oe=UTF…) verwenden.

Grüße, Robert

Hallo Thomas,

das kenne ich, meuterte auch anfangs heftig als man mir meine schönen C Pointer geraubt hatte…

Strings kannst du u.a. folgendermaßen „zerlegen“:

a) Wenn die Dinger eine feste Einteilung haben (bei dir ja anscheinend der Fall):
Klasse StringBuffer und die Methode substring(int start, int stop)
http://java.sun.com/j2se/1.4.1/docs/api/java/lang/St…

b) Wenn dir nur die Trennzeichen (" ", „-“ etc.) bekannt sind übernimmt das der StringTokenizer
http://java.sun.com/j2se/1.4.2/docs/api/java/util/St…

Etwas Generelles:
Als C++ler tendiert man gerne dazu mit Strings in Schleifen zu arbeiten (also sie zu zerteilen, konkatenieren etc.) - das ist aber unter Java pfui pfui.
Geht schon, nur müllst du dir deine VM mit x String-Objekten zu. Folgender Hintergrund: Strings sind in Java „immutable“ also unveränderbar. Sollen sie doch verändert werden, wird ein neues Objekt erzeugt und das alte „geistert“ in der VM herum bis es der garbage collector killt.
Für Stringoperationen wird der StringBuffer verwendet, welcher nicht immutable ist. Nicht vergessen am Ende der Operation einen „richtigen“ String zu erzeugen.

Gruss
Martin

Hallo Thomas,

zuallererst : mit dem Backslash am ende wirst du in Java eine Fehlermeldung bekommen und zwar das der String nicht abgeschlossen ist. Der Backslash maskiert das " und somit ist der String nicht abgeschlossen. Prüfe ob er sein muss, wenn ja dann ein doppelter Backslash \ , damit maskiert der erste den zweiten.

Ohne Backslash wäre die Lösung wie folgt auch zu erreichen:

–snipp–
import java.util.*;

public class StrAufloeser
{

public static void main(String[] args)
{
String s1=„PKF1234-APQ9283-RSZ095476383“ , feld, feldname, feldwert ;
StringTokenizer tokens= new StringTokenizer(s1, „-“ );

while(tokens.hasMoreTokens()){
feld= (String)tokens.nextToken();
feldname= feld.substring(0,3);
feldwert= feld.substring(4);

if(feldwert.endsWith("\")) {
feldwert= feldwert.substring(0,feldwert.length()-1);
}

System.out.println(" Feld\t" + feld + „\n“ +
" Feldname\t" + feldname + „\n“ +
" Feldwert\t" + feldwert + „\n“);
}

}

}

—snapp

Auch mit \ am Ende des Strings funktioniert es.

Eine StrAufloeser.java Datei erstellen und der Code reinkopieren, kompilieren fertig und staunen… *lol*

MfG.
Marc

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

erstmal vielen Dank für die Antworten.
@Marc: Deine Lösung gibt mir nur das letzte gefundene Feld aus. Mein Datensatz ist aber ziemlich lang(teilweise 10 Zeilen und länger) und die Feldnamen kommen öfter vor.
@BigRed: Ich habs jetzt so gemacht(ist das Pfui?):

int anfang[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int ende[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
String ergebnis[] = {"","","","","","","","","","","",""};
String feldname =„PQS“;
String such = „“;
int zaehler = 0;
int i = 0;
String trenner = „-“;
while(i

Hallo Thomas,

Während ich den String durchlaufe, schaue ich, ob ich den
gesuchten Feldnamen, hier PGN, finde.

du meinst „PQS“ - oder?

Wenn ich einen finde, lege ich die Position im Array „anfang“ ab.
Danach suche von dieser Position aus das Trennzeichen(-) und lege
diese Position in dem Array ende ab. Ist die Suche abgeschlossen,
kopiere ich in einer Schleife mit substring(anfang,ende)
sämtliche Suchergebnisse(Feldinhalte) im Array ergebnis ab.
Ist das ok oder müll ich damit alles zu? Funktionieren tuts
jedenfalls.

Sehe ich das richtig, dass du nur nach einem Muster also z. B. „PQSxxx“ oder „PKFxxx“ (wobei x irgendwelche Zahlen sind) suchst?

Das kannst du viel einfacher haben, hier ein erster 5-Min. Versuch ohne Anspruch auf Korrektheit:

 public List stringSucher(String suchstring, String muster) {
 List ergebnis = new ArrayList();
 int musterIdx = 0, trennerIdx = 0;

 while (true) {
 musterIdx = suchstring.indexOf(muster, trennerIdx);
 if (musterIdx == -1) break; //kein muster mehr da
 trennerIdx = suchstring.indexOf("-", musterIdx);
 if (trennerIdx == -1) trennerIdx = suchstring.length(); //bis zum Ende
 ergebnis.add(suchstring.substring(musterIdx, trennerIdx));
 }
 System.out.println(ergebnis.toString());
 return ergebnis;
 }

Wobei suchstring die komplette Nummer ist und muster dein Suchmuster wie „PQS“. In diesem Fall benötigt man keinen StringBuffer, da der Suchstring unverändert bleibt und nur Teile herausgeschnitten werden.

Gruss
Martin

Java 1.4 hat auch Reguläre Ausdrücke:
java.util.regex.*

Viele Grüsse
Simon

Hallo Martin,

klar mein PQS. Ich geb meiner Funktion den zu suchenden Feldnamen und vergleiche das mit drei aufeinanderfolgenden Zeichen in meinem Suchstring. Wenn ich was finde, kopier ich es raus und verändere den Suchstring also nicht. Die Ergebnisse landen dann in einem Ergebnisarray. Ist das so o.k. oder müll ich mir damit irgendwas zu?

Gruß
Thomas

Hallo Thomas,

ist schon OK so. „Müll“ produzierst du ja erst, wenn was am String selbst verändert werden soll.

Mein Vorschlag wäre halt dass du kein festes Ergebnisarray sondern eine Java-Collection wie z. B. die ArrayList verwendest. Ist meines Erachtens viel praktischer, vor allem wenn man nicht weiss wieviele Elemente da reinkommen sollen.

Gruss
Martin

Java 1.4 hat auch Reguläre Ausdrücke:
java.util.regex.*

Und dem, der das nicht hat kann ich von der Bedienbarkeit nur gnu.regexp empfehlen - Damit ich auch meinen Senf abgegeben habe :wink:

mfG,

J.P.Jarolim