2 Stimmen

java und regexp: wie man eine Zeichenfolge mit lithrealen Klammern übereinstimmen?

Ich habe diese drei Texte und einen Regexp. (OK, es ist HTML, aber ... bitte, konzentrieren Sie sich nicht darauf !!!!)

<h3 class="pubAdTitleBlock "><a href="stackoverflow.com/it/pubblicazioni/libri/Che-speranza-cè-per-i-morti/1101987030/" title="Che speranza c’è per i morti?">Che speranza c’è per i morti? (volantino N. 16)</a></h3>

<h3 class="pubAdTitleBlock "><a href="stackoverflow.com/it/pubblicazioni/libri/cosa-insegna-la-bibbia/È-questo-che-Dio-voleva/" title="È questo che Dio voleva?">Cosa insegna realmente la Bibbia?</a></h3>

<h3 class="pubAdTitleBlock">Cantiamo a Geova</h3>

Dies ist der Regexp

regexp = "<h3[^>]*>(<a[^>]*>)?([^<]+)(</a>)?</h3>";

Ich habe drei 3 Gruppen:

  • die Eröffnung <a> Tag (wahlweise)
  • der Text (es ist ein Buchtitel, das ist das Ziel von regexp )
  • die Schließung </a> Tag (wahlweise)

問題点 : Die zweite Reihe ist übereinstimmend, die dritte ist übereinstimmend. Die erste nicht. Warum?

Passender Code:

pattern = Pattern.compile(regexp);
matcher = pattern.matcher(fullString);
idx = 0;
while (matcher.find()) {
  ...
}

matcher.find() überspringt einfach die erste Zeile. Es handelt sich nicht um die erste Zeile der Datei, sondern um die 10. Es ist die erste des Beispiels.

Kann die wörtliche Klammer das Problem sein? Wie kann man die Regexp reparieren?

EDITAR : Ich habe versucht

String regexp = "<h3[^>]*>(.+)</h3>";

Aber auch diese Regexp überspringt die erste Zeile ... Ich kann wirklich nicht verstehen !!!!

EDIT 2:

Ich bin mit einem dubt: kann ein Problem sein, wenn es die akzentuierte Zeichen?

EDIT 3:

Ich versuche, von hier aus Daten zu scannen: http://www.jw.org/it/pubblicazioni/libri/?contentLanguageFilter=it&sortBy=3

Ich habe einen Eingabestrom, dann konvertiere ich mit diesem Code in einen einzelnen String:

 // copied from http://stackoverflow.com/questions/309424/read-convert-an-inputstream-to-a-string
public static String convertStreamToString(InputStream is) {
    try {
        return new java.util.Scanner(is, "UTF-8").useDelimiter("\\A").next();
    } catch (java.util.NoSuchElementException e) {
        return "";
    }

Dann wende ich die Regexp an ...

3voto

Pshemo Punkte 118094

Ich bin nicht sicher, aber vielleicht ist es das, wonach Sie suchen

String data = "<h3 class=\"pubAdTitleBlock \"><a href=\"/it/pubblicazioni/libri/Che-speranza-cè-per-i-morti/1101987030/\" title=\"Che speranza c’è per i morti?\">Che speranza c’è per i morti? (volantino N. 16)</a></h3>"
        + "<h3 class=\"pubAdTitleBlock \"><a href=\"/it/pubblicazioni/libri/cosa-insegna-la-bibbia/È-questo-che-Dio-voleva/\" title=\"È questo che Dio voleva?\">Cosa insegna realmente la Bibbia?</a></h3>"
        + "<h3 class=\"pubAdTitleBlock\">Cantiamo a Geova</h3>";

Pattern pattern = Pattern
        .compile("<h3[^>]*>(?:<a[^>]*>)?([^<]+)(?:</a>)?</h3>");
Matcher matcher = pattern.matcher(data);
while (matcher.find()) 
    System.out.println(matcher.group(1));

出力します:

Che speranza c’è per i morti? (volantino N. 16)
Cosa insegna realmente la Bibbia?
Cantiamo a Geova

Kleine Erklärung:

Gruppen wie (?:someregex) wird vom Regex-Mechanismus nicht gezählt. Dank dieser in (?:a)(b)(?:c)(d) Gruppe (b) wird als 1 indiziert und (d) wie 2.

Bearbeiten1

(Ich weiß, dass es Blasphemie ist, Regex zum Parsen von HTML zu verwenden, aber da OP es wünscht...)
Sie haben vergessen zu erwähnen, dass geparstes HTML Leerzeichen enthält wie Tabellen y neue Linie Markierungen innen <h3 > . Versuchen Sie es auf diese Weise:

String data = convertStreamToString(new URL(
        "http://www.jw.org/it/pubblicazioni/libri/?contentLanguageFilter=it&sortBy=3")
        .openStream());

Pattern pattern = Pattern
        .compile("<h3[^>]*>\\s*(?:<a[^>]*>)?([^<]+)(?:</a>)\\s*?</h3>");
Matcher matcher = pattern.matcher(data);
int counter=0;
while (matcher.find())
    System.out.println(++counter +")"+matcher.group(1));

出力します:

1)Accostiamoci a Geova
2)Accostiamoci a Geova — caratteri grandi
....
11)Cosa insegna realmente la Bibbia?
12)Cosa insegna realmente la Bibbia? — caratteri grandi

2voto

Anton Bessonov Punkte 8498

Tun Sie es nicht mit Parser oder RegExp. Versuchen Sie Jerry . Wie (nicht getestet):

Jerry doc = jerry(html);
doc.$("a").each(new JerryFunction() {
    public boolean onNode(Jerry $this, int index) {
        String href = $this.attr("href");
        System.out.println(href);
    }
}

oder eine andere html-freundliche Abfragesprache. Wegen der nicht-externen Anforderungen versuchen Versuch, Links in einer HTML-Verzeichnisliste mit Java zu analysieren

(Ich habe meine Antwort kopiert von: Wie kann man mit Java Links aus HTML analysieren? )

EDIT: Versuchen Sie

<h3.*?>(<a.*)?+(.*?)(</a>)?</h3>

und erhalten Gruppe(2)

EDIT 2: Versuchen Sie es einfach mal mit dem Buchtitel:

(.*>)?([^<]+?)<.*

EDIT 3: Ihr Regexp

<h3[^>]*>(<a[^>]*>)?([^<]+)(</a>)?</h3>

scheint für mich zu funktionieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X