Reguläre Ausdrücke und JAVA

benomatic

Grünschnabel
Hallo Leute,

ich habe endlich das Prinzip von Pattern und Matchern in Java verstanden trotzdem vermisse ich einige "feature" die ich von Perl her kenne.

Mein Problem ist folgendes:

Code:
Pattern p1 = Pattern.compile("ab \\d\\d:\\d\\d");
URLConnection con = new URL(url).openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
		while (br.ready()) {
			tmp = br.readLine();
			if (p1.matcher(tmp).find()) { // Pattermatching
				System.out.println(tmp);
			}
		}
		br.close();

Ausgabe ist dies:
Code:
<td class="color3" headers="aban1">ab 14:00</td>
<td class="color3" headers="aban1">ab 14:06</td>
<td class="color3" headers="aban1">ab 14:07</td>

Gibt es die Möglichkeit nach "ab \d\d:\d\d" zu suchen um dann wiederum
an die "stunden" und "Minuten" zukommen als int.

Wäre sehr cool wenn mir einer nen Tip geben könnte wie ich nach einem SubString im String suchen und ausgeben kann, ohne die gesamte Zeile.

Ich glaube der Perl code wäre sowas:
Code:
$string =~m/regexp/$1/g;
$subString = $1;
 

takidoso

Erfahrenes Mitglied
Hallo Leute,

Ausgabe ist dies:
Code:
<td class="color3" headers="aban1">ab 14:00</td>
<td class="color3" headers="aban1">ab 14:06</td>
<td class="color3" headers="aban1">ab 14:07</td>

Gibt es die Möglichkeit nach "ab \d\d:\d\d" zu suchen um dann wiederum
an die "stunden" und "Minuten" zukommen als int.

Wenn ich Dich richtig verstehe möchtest Du aus "<td class="color3" headers="aban1">ab 14:00</td>" die Stunden und Minuten haben..
Wenn ich Dein Programmcode richtig verstehe hast Du da so eine Art grep programiert (hole mal die Zeile die einem bestimmten Muster entspricht..)
Also eine Möglichkeit wäre, wenn man weiß dass die zu untersuchenden Zeilen alle homogen sind, einfach mit dem Offset der gewünschten Zeichenkette zu arbeiten und mit enem Substring zu arbeiten. Da aber die Welt nicht immer so statisch ist ;-) habe ich da eine Kanone für Dich, die auch Deinen Spatz abschießen könnte :-D

Da habe ich doch glatt eine Klasse die Dir vielleicht weiterhefen könnte...
Ich nenne sie StringComposer, Mit der kannst Du einen String zerlegen und so ziemlich jeden beliebigen String konstruieren, inklusive sequenziellen Nummernr, TimeStamps und wenn Du magst auch Properties. Als Eingangsinformation dienen unter anderem ein Eingangsmuster (RegEx) der Quell-String und ein Ausgangsmuster, welches eine eigene Syntax hat, di eaber relativ leicht zu lernen ist. Das Ausgangmuster kann bei Bedarf die potenziell im Eingangsmuster verwendeten Gruppen in den neuen String einbeziehen.

Für Dein Beispiel wäre es vermutlich wie folgt
Code:
String inputStr         = geleseneZeile;
String inputMuster   = "<td.*>ab (\\d{2}):(\\d{2})</td>";  //Gruppe 1= Stunden Gruppe 2 = Minuten
String outputMuster = "(1)";
StringComposer strComp = new StringComposer(new Map()  // nur als Dummy
                                                                        inputMuster ,
                                                                        inputStr,
                                                                        outputPattern);
String stunden = strComp.constructString();
outputMuster   = (2);
strComp          = new StringComposer(new Map()  // nur als Dummy
                                                         inputMuster ,
                                                         inputStr,
                                                         outputPattern);
String minuten = strComp.constructString();

Im Anhang sind die notwendigen Klassen als .txt musst dann natürlich noch die Paketangabe nach Deinem Wohldünken angeben. (mach damit was Du magst, verübe aber keinen terroristischen Anschlag :p

viel Spaß damit

Takidoso
 

Anhänge

  • AutoCounter.txt
    13,4 KB · Aufrufe: 26
  • StringComposer.txt
    26,7 KB · Aufrufe: 30

zeja

Erfahrenes Mitglied
Öhm wenn ich das richtig verstanden habe reicht doch folgendes völlig:
Java:
public static void main(String[] args) {
	final String search = "<td class=\"color3\" headers=\"aban1\">ab 14:00</td>";
	final String regExp = "ab (\\d\\d):(\\d\\d)";
	
	Pattern p = Pattern.compile(regExp);
	final Matcher matcher = p.matcher(search);
	
	if(matcher.find()){
		String hours = matcher.group(1);
		String minutes = matcher.group(2);
		System.out.println(hours + " " + minutes);
	}
	else{
		System.out.println("String not found");
	}
}

Ausgabe:
Code:
14 00
 

takidoso

Erfahrenes Mitglied
Hi Zeja,
ja Du hast recht, Deine Lösung ist die direktere und für dieses Problem betreffend möglicherweies auch die angebrachtere.
Aber ich wollte doch nur (ganz stolz) die Kanone für den Spatz bieten :p.
Die Klasse ist gut, sobald es darum geht Strings neu zusammenzubasteln, sei es aus persistenten, laufenden Nummern beliebigen Formats, TimeStamps beliebigem Formats, anderen festen Stringbestandteilen, Properties (voreingestellt sind Systemproperties), oder (und) Bestandteilen eines Eingangsstrings.
Ursprünglich hatte ich den StingComposer wegen Dateiumbenennungen gebaut und vielleicht hat ja jemand irgendwann ähnliche Bedürfnisse.

Der momentane Zustand mit den "home-brewed" AutoCountern ist vielleicht etwas plump. Man würde hier vielleicht hin und wieder lieber auf einen Zähler einer Datenbank zurückgreifen wollen. Empfehlenswert wäre daher bei einer Erweiterung des Ganzen ein sinniges Interface zwischen "AutoCounter" und "StringComposer" zu etablieren, damit dann auch beispielsweise Oracle-Sequences zum Einsatz kommen könnten. Das überlasse ich aber gerne jedem selbst.
 
Zuletzt bearbeitet: