schwieriger RegExp

Status
Nicht offen für weitere Antworten.

micbur

Bekanntes Mitglied
Hallo,

ich möchte Teile aus der Javadoc parsen. Hierfür hatte ich mir einen RegExp ausgedacht, der aber nicht funktioniert. Und ich weiß nicht warum.

Nehmen wir an, ich möchte aus der <javadoc>/java/lang/String.html die Details vom Feld 'CASE_INSENSITIVE_ORDER', dann kann ich im HTML-Quelltext nach dem String '<A NAME="CASE_INSENSITIVE_ORDER"></A>' suchen. Der entsprechende RegExp wäre meiner Meinung nach:
Code:
searchPattern = "<A NAME=\\\"CASE_INSENSITIVE_ORDER\\\"></A>";

Dieser Pattern wird aber nicht gefunden.

Wo hingegen mir von
Code:
System.out.println(html.indexOf("<A NAME=\"CASE_INSENSITIVE_ORDER"));
der Index 50853 ausgegeben wird.

Es ist da, aber mein RegExp ist falsch.
Wo?

Ich brauche da Hilt, bitte. Ich suche schon seit Stunden ohne Erfolg und mit der Doku in der Hand, fällt mir mein Fehler nicht auf.

Ciao, micbur
 
S

SlaterB

Gast
was spricht gegen searchPattern
"<A NAME=\"CASE_INSENSITIVE_ORDER\"></A>"
?

Code:
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {

	public static void main(String args[]) {
		String st = "<A NAME=\"CASE_INSENSITIVE_ORDER\"></A>";

		System.out.println(st);
		System.out.println(st.indexOf(st));
		Pattern p = Pattern.compile(st);
		Matcher m = p.matcher(st);
		boolean b = m.find();
		System.out.println(b);
	}
}
 

micbur

Bekanntes Mitglied
Was dagegen spricht?
Also ich spreche nicht dagegen, nur Java.

Code:
	String         searchPattern = "<A NAME=\\\"" + fragment + "\\\"></A>"; // fragment ist ein String (Parameter)
	fileInput = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
	while ( (line = fileInput.readLine()) != null ) {
		totalFile.append(line + "\n"); // totalFile ist ein StringBuffer
	}

	System.out.println(searchPattern); // Ausgabe: <A NAME=\"CASE_INSENSITIVE_ORDER\"></A>
	System.out.println(totalFile.indexOf("<A NAME=\"" + fragment + "\"></A>")); // Ausgabe: 50853; wird also gefunden
	if ( Pattern.matches( searchPattern , totalFile.toString() ) ) {
		System.out.println("pling");
	}
	else {
		System.out.println("plong");
	}

Ich hätte gerne ein 'pling', bekomme aber nur 'plong's.
 

hupfdule

Top Contributor
micbur hat gesagt.:
Code:
	System.out.println(searchPattern); // Ausgabe: <A NAME=\"CASE_INSENSITIVE_ORDER\"></A>

Hättest du SlaterBs Pattern genommen, wäre die Ausgabe:
Code:
<A NAME="CASE_INSENSITIVE_ORDER"></A>
 

micbur

Bekanntes Mitglied
hupfdule hat gesagt.:
Hättest du SlaterBs Pattern genommen, wäre die Ausgabe:
Code:
<A NAME="CASE_INSENSITIVE_ORDER"></A>
Ja, und?

Das ist nicht besser. Immerhin muss ich bei Pattern noch gewisse Zeichen 'escapen', zum Beispiel: " oder ' oder \.
Außerdem habe ich es auch versucht, noch ein Fehlversuch schadet ja nicht, aber es geht auch nicht.
 
S

SlaterB

Gast
weißt du üerhaupt was Pattern.matches() macht?

meiner Meinung nach prüft das, ob die gesamte Datei dem Pattern entspricht,
was wohl nicht der Fall ist, falls die gesamte Datei nicht NUR aus
"<A NAME="CASE_INSENSITIVE_ORDER"></A>" besteht,

warum machst du das nur so kompliziert?
lass doch das File weg und lege dir einen TestString an,
dann versuche dich erstmal an einem einfachen Pattern 'A',
danach höheres

im Gegensatz zu matches() gibt es andere Operationen wie find(), group() in Matcher,
evtl. habe ich das ganze aber auch selber falsch verstanden ;)
 

micbur

Bekanntes Mitglied
ja, eigentlich fehlen vorne und hinten noch ".*", aber das hatte auch schon nicht funktioniert. Selbst ".*" wird nicht gefunden, obwohl der Inhalt der Datei ja auch beliebigen Zeichen mit beliebiger Häufigkeit besteht.
 
S

SlaterB

Gast
wunderbar, ein Pattern aus zwei Zeichen (.*) funktioniert bei dir nicht,
ich gehe dann nach lokalen Tests auch davon aus, das jegliches Pattern auf diese langen Dateien bei dir nicht geht,
aber du fragst nach so einem 30 Zeichen langen Pattern ;)

komplexe Dateien einlesen, Pattern mit Parameter erstellen,
aber die einfachsten Grundlagen nicht an einfachen Strings testen?

diese Vorgehensweise solltest du mal überdenken,
denn in so einem Riesenprogramm ist die Fehlersuche weitaus schwieriger

----------

wie in der API bei Pattern nachzulesen ist (wieso muss ich das eigentlich tun ;) )
kommt . nicht unbedingt auch mit Zeilenumbrüchen klar

deine 1000-Zeichen-Datei kannst du also immer noch vergessen,
stattdessen tritt das gleiche Problem in dem winzigen String "\n" genauso auf,

Lösung: gibt sicher mehrere, kenn mich da nicht aus,
bin zufrieden wenn ich eine gefunden habe:



Code:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {

	public static void main(String args[]) throws Exception {
//		StringBuffer totalFile = new StringBuffer();
//		String line = null;
//		BufferedReader fileInput =
//			new BufferedReader(
//				new InputStreamReader(
//					new FileInputStream(new File("Broetchen.java"))));
//		while ((line = fileInput.readLine()) != null) {
//			totalFile.append(line + "\n"); 
//		}
//		fileInput.close();

		String st = "\nx \n";
		//st = totalFile.toString();
		String searchPattern = ".*";

		System.out.println(st);
		System.out.println(searchPattern);
		Pattern p = Pattern.compile(searchPattern, Pattern.DOTALL);
		Matcher m = p.matcher(st);
		if (m.matches()) {
			System.out.println("pling");
		} else {
			System.out.println("plong");
		}
	}
}
 

micbur

Bekanntes Mitglied
Hmmm, das mit den Zeilenumbrüchen bin ich noch von Perl/Bash gewohnt - ein \n ist auch nur ein Zeichen. Wahrscheinlich bin ich bei der Doku bei den ganzen Posix-Unicode-Zeuges zusammen geklappt.
\p{blöööp} lol, man kann es auch schwer machen.

Dachte immer, die Stärke von RegExp liegt in der Einfachheit und Gleichbehandlung aller Zeichen, außer Steuerzeichen für RegExp.

Aber vielen Dank, dass du für mich nachgeschaut hast. Ist wieder so eine implizite Annahme gewesen: funktioniert hier, also auch dort. Oder wie Mario Barth sagte: Hose passt im Laden, ergo Hose passt auch zu Hause.

Naja, das Licht bei Java ist halt ein bisschen anders.

Ciao, micbur
 

micbur

Bekanntes Mitglied
Hallo,

ich hatte mich noch einem anderen Problem zugewandt, daher hat das so gedauert.

Ich habe zwar jetzt mein 'pling', aber irgendwie hatte ich mich das so vorgestellt, dass mir der Matcher zwei Positionen verraten könnte, also sowas wie Anfang und Ende des Matches, oder nur den Anfang.

Code:
		StringBuffer stb = new StringBuffer("");
		stb.append("<A NAME=\"field_detail\"></A>\n");
		stb.append("<TABLE BORDER=\"1\" WIDTH=\"100%\" CELLPADDING=\"3\" CELLSPACING=\"0\" SUMMARY=\"\">\n");
		stb.append("<TR BGCOLOR=\"#CCCCFF\" CLASS=\"TableHeadingColor\">\n");
		stb.append("<TH ALIGN=\"left\" COLSPAN=\"1\"><FONT SIZE=\"+2\">\n");
		stb.append("[B]Field Detail[/B]</FONT></TH>\n");
		stb.append("</TR>\n");
		stb.append("</TABLE>\n");
		stb.append("<A NAME=\"CASE_INSENSITIVE_ORDER\"></A><H3>\n");
		stb.append("CASE_INSENSITIVE_ORDER</H3>\n");
		stb.append("<PRE>\n");
		stb.append("public static final <A HREF=\"../../java/util/Comparator.html\" title=\"interface in java.util\">Comparator</A>&<A HREF=\"../../java/lang/String.html\" title=\"class in java.lang\">String</A>& [B]CASE_INSENSITIVE_ORDER[/B]</PRE>\n");
		stb.append("<DL>\n");
		stb.append("<DD>A Comparator that orders <code>String</code> objects as by\n");
		stb.append(" <code>compareToIgnoreCase</code>. This comparator is serializable.\n");
		stb.append(" 

\n");
		stb.append(" Note that this Comparator does [i]not[/i] take locale into account,\n");
		stb.append(" and will result in an unsatisfactory ordering for certain locales.\n");
		stb.append(" The java.text package provides [i]Collators[/i] to allow\n");
		stb.append(" locale-sensitive ordering.\n");
		stb.append("

\n");
		stb.append("<DL>\n");
		stb.append("<DT>[B]Since:[/B]</DT>\n");
		stb.append("  <DD>1.2</DD>\n");
		stb.append("<DT>[B]See Also:[/B]<DD><A HREF=\"../../java/text/Collator.html#compare(java.lang.String, java.lang.String)\"><CODE>Collator.compare(String, String)</CODE></A></DL>\n");
		stb.append("</DL>\n");

		String searchPattern = ".*<A NAME=\"CASE_INSENSITIVE_ORDER\"></A>.*";

		// System.out.println(stb);
		System.out.println(searchPattern);
		Pattern p = Pattern.compile(searchPattern, Pattern.DOTALL);
		Matcher m = p.matcher(stb);
		if (m.matches()) {
			System.out.println(m.start() + " - " + m.end());
		} else {
			System.out.println("plong");
		}

Ich weiß, dass mein Suchpattern nicht gut ist, aber nun fällt mir wirklich nicht mehr ein, wie ich an die Position des Ankers komme. Irgendwie ist mein roter Faden weg.

Hat jemand eine Idee, wie ich mittels RegExp jetzt da rankomme?
regionStart(), start,() group() habe ich schon probiert - die bringen mir immer 0.

Ciao, micbur
 
S

SlaterB

Gast
dein Fortschritt vom File zum String ist schon mal lobenswert,
allerdings für die neue Frage völlig überdimensioniert,

wieder hast du es mit einem grundsätzlichen Problem zu tun,
dass nämlich überhaupt keine Positionen gefunden werden,

dies testet mal idealerweise z.B. mit der Suche nach 'a' im String 'abcdae',
nicht in 27 Zeilen StringBuffer ;)

----------

wie am Anfang diskutiert, arbeitet matches nur mit dem Gesamtstring,
dein Pattern kümmert sich ja auch um den Gesamtstring (.*),
was hat das nun mit einer einzelnen Position zu tun?

dafür musst du wieder zu dem Pattern ohne .* zurückkehren,
Beispiel:
Code:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {

	public static void main(String args[]) throws Exception {

		String st = "sabcdabababe";
		String searchPattern = "ab";

		System.out.println(st);
		System.out.println(searchPattern);
		Pattern p = Pattern.compile(searchPattern, Pattern.DOTALL);
		Matcher m = p.matcher(st);

		while (m.find()) {
			System.out.println(
				"Ein Vorkommen gefunden von Index "
					+ m.start()
					+ " bis "
					+ m.end()
					+ ".");
		}
	}

}
 

micbur

Bekanntes Mitglied
Hallo Slater,

vielen Dank für deine Hilfe. Falls du mal ein Programm brauchst, dass die Javadocs durchsucht, nimm' diese Pattern. Sie funktionieren auf den Javadocs von 1.3 bis 1.5 (andere nicht getestet).

Code:
	Pattern startPattern     = Pattern.compile("<A NAME=\"" + fragment + ".*\"></A>", Pattern.DOTALL);
	Pattern endPattern       = Pattern.compile("</DL>(</DD>|\n)+(<HR>|</DL>)", Pattern.DOTALL);

Bei 'fragment' muss der Identifier rein, den du suchst, also ein Constructor, eine Methode oder ein Feld. Leider wird so nur der erste Konstruktor, die erste Methode und das erste Feld gefunden, die darauf passen. Sollte also dein Konstruktur, wie bei String, überladen sein, wird der Konstruktor gefunden, der oben in der Javadoc steht.

Ciao, micbur

[closed]
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben