使用多行正则表达式进行HTML解析

问题描述 投票:0回答:1

当前,我正在用Java编写程序,在这里我必须解析html文件并从表中获取所有名称。我必须用纯Java编写它,所以不能使用Jsoup或类似的东西。

html的片段在这里:

<table class="wikitable toptextcells" width="100%">
<tbody><tr>
<th width="50%">Comic
</th>
<th width="50%">Film
</th></tr>
<tr>
<td colspan="2" class="hintergrundfarbe2">
<h3><span id="0.E2.80.939"></span><span class="mw-headline" id="0–9"><span id="Real-0–9"></span> 0–9</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="https://de.wikipedia.org/w/index.php?title=Liste_von_Comicverfilmungen&amp;veaction=edit&amp;section=2" class="mw-editsection-visualeditor" title="Abschnitt bearbeiten: 0–9">Bearbeiten</a><span class="mw-editsection-divider"> | </span><a href="https://de.wikipedia.org/w/index.php?title=Liste_von_Comicverfilmungen&amp;action=edit&amp;section=2" title="Abschnitt bearbeiten: 0–9">Quelltext bearbeiten</a><span class="mw-editsection-bracket">]</span></span></h3>
</td></tr>
<tr>
<td>2 Guns
</td>
<td><a href="https://de.wikipedia.org/wiki/2_Guns" title="2 Guns">2 Guns</a> (2013)
</td></tr>
<tr>
<td>5 ist die perfekte Zahl (von <a href="https://de.wikipedia.org/wiki/Igort" title="Igort">Igort</a>)
</td>
<td>5 è il numero perfetto (2019)
</td></tr>
<tr>
<td>13 rue de l'Espoir (von <a href="https://de.wikipedia.org/wiki/Paul_Gillon" title="Paul Gillon">Paul Gillon</a>)
</td>
<td>Die tolle Masche (1961)
</td></tr>
<tr>
<td rowspan="2"><a href="https://de.wikipedia.org/wiki/XIII_(Comicserie)" title="XIII (Comicserie)">XIII</a>
</td>
<td><a href="https://de.wikipedia.org/wiki/XIII_%E2%80%93_Die_Verschw%C3%B6rung" title="XIII – Die Verschwörung">XIII – Die Verschwörung</a> (Fernseh-Zweiteiler, 2008)
</td></tr>
<tr>
<td><a href="https://de.wikipedia.org/wiki/XIII_%E2%80%93_Die_Verschw%C3%B6rung_(Fernsehserie)" title="XIII – Die Verschwörung (Fernsehserie)">XIII – Die Verschwörung</a> (Fernsehserie, 2011–2012)
</td></tr>
<tr>
<td rowspan="3"><a href="https://de.wikipedia.org/wiki/20th_Century_Boys" title="20th Century Boys">20th Century Boys</a>
</td>
<td>20th Century Boys 1 (2008)
</td></tr>
<tr>
<td>20th Century Boys 2 (2009)
</td></tr>
<tr>
<td>20th Century Boys 3 (2009)
</td></tr>
<tr>
<td rowspan="2">30 Days of Night
</td>
<td><a href="https://de.wikipedia.org/wiki/30_Days_of_Night" title="30 Days of Night">30 Days of Night</a> (2007)
</td></tr>
<tr>
<td><a href="https://de.wikipedia.org/wiki/30_Days_of_Night:_Dark_Days" title="30 Days of Night: Dark Days">30 Days of Night: Dark Days</a> (2010)
</td></tr>
<tr>
<td rowspan="2">47:an Löken (von Lennart Elworth)
</td>
<td>47:an Löken (1971)
</td></tr>
<tr>
<td>47:an Löken blåser på (1972)
</td></tr>
<tr>
<td rowspan="8">91:an Karlsson (von <a href="https://de.wikipedia.org/wiki/Rudolf_Petersson" title="Rudolf Petersson">Rudolf Petersson</a>)
</td>
<td>Aber warum, Herr Feldwebel? (1946)
</td></tr>
<tr>
<td>Zurück, marsch-marsch! (1947)
</td></tr>
<tr>
<td>Rekruten rechts 'raus (1951)
</td></tr>
<tr>
<td>Alla tiders 91:an Karlsson (1953)
</td></tr>
<tr>
<td>91 Karlsson rycker in (1955)
</td></tr>
<tr>
<td>91:an Karlsson slår knock out (1957)
</td></tr>
<tr>
<td>91:an Karlsson muckar (tror han) (1959)
</td></tr>
<tr>
<td>91:an och generalernas fnatt (1977)
</td></tr>
<tr>
<td rowspan="2"><a href="https://de.wikipedia.org/wiki/300_(Comic)" title="300 (Comic)">300</a>
</td>
<td><a href="https://de.wikipedia.org/wiki/300_(Film)" title="300 (Film)">300</a> (2007)
</td></tr>
<tr>
<td><a href="https://de.wikipedia.org/wiki/300:_Rise_of_an_Empire" title="300: Rise of an Empire">300: Rise of an Empire</a> (2014)
</td></tr>
<tr>
<td colspan="2" class="hintergrundfarbe2">
<h3><span class="mw-headline" id="A"><span id="Real-A"></span> A</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="https://de.wikipedia.org/w/index.php?title=Liste_von_Comicverfilmungen&amp;veaction=edit&amp;section=3" class="mw-editsection-visualeditor" title="Abschnitt bearbeiten: A">Bearbeiten</a><span class="mw-editsection-divider"> | </span><a href="https://de.wikipedia.org/w/index.php?title=Liste_von_Comicverfilmungen&amp;action=edit&amp;section=3" title="Abschnitt bearbeiten: A">Quelltext bearbeiten</a><span class="mw-editsection-bracket">]</span></span></h3>
</td></tr>
<tr>
<td>Abattoir (Radical Studios)
</td>
<td>Abattoir – Er erwartet dich! (2016)
</td></tr>
<tr>
<td>Ace Drummond (von <a href="https://de.wikipedia.org/wiki/Edward_Vernon_Rickenbacker" title="Edward Vernon Rickenbacker">Eddie Rickenbacker</a> und Clayton Knight)
</td>
<td>Ace Drummond (Serial, 1936)
</td></tr>
<tr>
<td>Accident Man (von Pat Mills u.&nbsp;a.)
</td>
<td>Accident Man (2018)
</td></tr>
<tr>
<td>Ada im Dschungel (von <a href="https://de.wikipedia.org/wiki/Francesco_Tullio_Altan" title="Francesco Tullio Altan">Altan</a>)
</td>
<td>Ada dans la jungle (1988)
</td></tr>
<tr>
<td rowspan="6"><a href="https://de.wikipedia.org/wiki/The_Addams_Family" title="The Addams Family">The Addams Family</a> (Zeitungscartoons)
</td>
<td>Die Addams Family (Fernsehserie, 1964–1966)
</td></tr>
<tr>
<td>Halloween with the New Addams Family (1977)
</td></tr>
<tr>
<td><a href="https://de.wikipedia.org/wiki/Addams_Family_(1991)" title="Addams Family (1991)">Addams Family</a> (1991)
</td></tr>
<tr>
<td><a href="https://de.wikipedia.org/wiki/Die_Addams_Family_in_verr%C3%BCckter_Tradition" title="Die Addams Family in verrückter Tradition">Die Addams Family in verrückter Tradition</a> (1993)
</td></tr>
<tr>
<td><a href="https://de.wikipedia.org/wiki/Addams_Family_%E2%80%93_Und_die_lieben_Verwandten" title="Addams Family – Und die lieben Verwandten">Addams Family – Und die lieben Verwandten</a> (1998)
</td></tr>
<tr>
<td><a href="https://de.wikipedia.org/wiki/Die_neue_Addams_Familie" title="Die neue Addams Familie">Die neue Addams Familie</a> (Fernsehserie, 1998–1999)
</td></tr>
<tr>
<td><a href="https://de.wikipedia.org/wiki/Adeles_ungew%C3%B6hnliche_Abenteuer" title="Adeles ungewöhnliche Abenteuer">Adeles ungewöhnliche Abenteuer</a>
</td>
<td><a href="https://de.wikipedia.org/wiki/Ad%C3%A8le_und_das_Geheimnis_des_Pharaos" title="Adèle und das Geheimnis des Pharaos">Adèle und das Geheimnis des Pharaos</a> (2010)
</td></tr>
<tr>
<td><a href="https://de.wikipedia.org/wiki/Figuren_aus_dem_Marvel-Universum#Margaret_%E2%80%9EPeggy%E2%80%9C_Carter" title="Figuren aus dem Marvel-Universum">Agent Carter</a>
</td>
<td><a href="https://de.wikipedia.org/wiki/Marvel%E2%80%99s_Agent_Carter" title="Marvel’s Agent Carter">Marvel’s Agent Carter</a> (Fernsehserie, 2015–2016)
</td></tr>
<tr>
<td>Air Hawk (von John Dixon)
</td>
<td>Air Hawk (1981)
</td></tr>
<tr>
<td>Alena (von Kim W. Andersson)
</td>
<td>Alena (2015)
</td></tr>
<tr>
<td><a href="https://de.wikipedia.org/wiki/Alexander_Nikopol" title="Alexander Nikopol">Alexander Nikopol</a> (<i>Die Geschäfte der Unsterblichen</i>)
</td>
<td><a href="https://de.wikipedia.org/wiki/Immortal_%E2%80%93_New_York_2095:_Die_R%C3%BCckkehr_der_G%C3%B6tter" title="Immortal – New York 2095: Die Rückkehr der Götter">Immortal – New York 2095: Die Rückkehr der Götter</a> (2004)
</td></tr>
<tr>
<td><a href="https://de.wikipedia.org/wiki/Allein_(Comic)" title="Allein (Comic)">Allein</a>
</td>
<td>Seuls (2017)
</td></tr>
<tr>
<td><a href="https://de.wikipedia.org/wiki/Der_allt%C3%A4gliche_Kampf" title="Der alltägliche Kampf">Der alltägliche Kampf</a> (von <a href="https://de.wikipedia.org/wiki/Manu_Larcenet" title="Manu Larcenet">Manu Larcenet</a>)
</td>
<td>Le Combat ordinaire (2015)
</td></tr>
<tr>
<td rowspan="3">Ally Sloper (von Marie Duval und C. H. Ross)
</td>
<td>Ally Sloper (Kurzfilm, 1898)
</td></tr>
<tr>
<td>Sloper's Visit to Brighton (Kurzfilm, 1898)
</td></tr>
<tr>
<td>Ally Sloper (Kurzfilm-Serie, 1921)
</td></tr>
<tr>
<td rowspan="2"><a href="https://de.wikipedia.org/w/index.php?title=Along_with_the_Gods_(Webtoon)&amp;action=edit&amp;redlink=1" class="new" title="Along with the Gods (Webtoon) (Seite nicht vorhanden)">Along with the Gods</a>
</td>
<td><a href="https://de.wikipedia.org/wiki/Along_with_the_Gods:_The_Two_Worlds" title="Along with the Gods: The Two Worlds">Along with the Gods: The Two Worlds</a> (2017)
</td></tr>
<tr>
<td><a href="https://de.wikipedia.org/wiki/Along_with_the_Gods:_The_Last_49_Days" title="Along with the Gods: The Last 49 Days">Along with the Gods: The Last 49 Days</a> (2018)
</td></tr>
<tr>
<td>Alphonse and Gaston (von <a href="https://de.wikipedia.org/wiki/Frederick_Burr_Opper" title="Frederick Burr Opper">Frederick Burr Opper</a>)
</td>
<td>Alphonse and Gaston (Kurzfilm-Serie, 1902–1903)
</td></tr>
</tbody></table>
<h2><span class="mw-headline" id="Anmerkung_zu_Trickfilmen_und_Comiczeichnern">Anmerkung zu Trickfilmen und Comiczeichnern</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="https://de.wikipedia.org/w/index.php?title=Liste_von_Comicverfilmungen&amp;veaction=edit&amp;section=57" class="mw-editsection-visualeditor" title="Abschnitt bearbeiten: Anmerkung zu Trickfilmen und Comiczeichnern">Bearbeiten</a><span class="mw-editsection-divider"> | </span><a href="https://de.wikipedia.org/w/index.php?title=Liste_von_Comicverfilmungen&amp;action=edit&amp;section=57" title="Abschnitt bearbeiten: Anmerkung zu Trickfilmen und Comiczeichnern">Quelltext bearbeiten</a><span class="mw-editsection-bracket">]</span></span></h2>

[起初,我只想匹配其中有两个<tr><td>,但我不知道为什么它不起作用。我在www.regex101.com上检查了我的正则表达式,这似乎很好。但是在Java中,我必须用。*替换\ n?甚至得到一场比赛。这是我的Java代码:

import utils.YearInterval;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Parser {
    private Pattern comicBegin = Pattern.compile("<h3><span id=\"0\\.E2\\.80\\.939\"></span>.*?</h3>", Pattern.MULTILINE | Pattern.DOTALL);
    private Pattern comicEnd = Pattern.compile("<h2><span class=\"mw-headline\" id=\"Anmerkung_zu_Trickfilmen_und_Comiczeichnern\">.*?</h2>", Pattern.MULTILINE | Pattern.DOTALL); 
    private Pattern comicEnum = Pattern.compile("<tr>.*?<td.*?>(?:<a.*?\">)?(.*?)(?:</a.*?>)?.*?</td>.*?<td>(?:<a.*?>)?(.*?)(?:</a>)?.*?</td></tr>", Pattern.MULTILINE | Pattern.DOTALL);  // Tried also this <tr>\\n<td.*?>(?:<a.*?">)?(.*?)(?:</a.*?>)?\\n</td>\\n<td>(?:<a.*?>)?(.*?)(?:</a>)?\\n</td></tr>
    private Scanner wikiComicFilmScanner = null;

    public static void main(String[] args) throws MalformedURLException, IOException {
        Path wikiComicFilmLocal = Paths.get("ressources/ListevonComicverfilmungen.html");
        Parser wp1 = new Parser("file:///" + wikiComicFilmLocal.toAbsolutePath());
        long start = System.currentTimeMillis();
        Map<String, Map<YearInterval, List<String>>> comicMap = wp1.contentToComicFilmsPerYear();
        System.out.println("Parsen ausgeführt in: " + (System.currentTimeMillis() - start) + "ms");
    }

    public Parser(String uri) throws MalformedURLException, IOException {
        wikiComicFilmScanner = new Scanner(new URL(uri).openStream(), "UTF-8");
    }


    public Map<String, Map<YearInterval, List<String>>> contentToComicFilmsPerYear() {
        Map<String, Map<YearInterval, List<String>>> comicMap = new HashMap<>();
        wikiComicFilmScanner.useDelimiter(comicBegin);
        if (wikiComicFilmScanner.hasNext()) {
            wikiComicFilmScanner.next();
        }
        wikiComicFilmScanner.useDelimiter(comicEnd);
        if (wikiComicFilmScanner.hasNext()) {
            String filmsPerYearEnumeration = wikiComicFilmScanner.next();
            Matcher matcherEnum = comicEnum.matcher(filmsPerYearEnumeration);
            while (matcherEnum.find()) {
                String comicTitle = matcherEnum.group(0);
                String filmTitle = matcherEnum.group(2);
                System.out.println("---------------------------------");
                System.out.println(comicTitle);
                System.out.println(filmTitle);
            }
        }
        return comicMap;
    }

}

非常感谢!

java html regex parsing multiline
1个回答
0
投票

取决于HTML的来源,新行可能不仅是\n(Unix,新的Mac),还可能是\r(古代Mac)或\r\n(Windows)。请注意,这取决于HTML的创建者,不一定取决于您自己的系统。

根据Regular Expression to match cross platform newline characters,建议用于与平台无关的换行符的表达式是"\r\n?|\n"

这将符合以下任何条件:

  • \r\n
  • \r
  • \n
© www.soinside.com 2019 - 2024. All rights reserved.