Regex Hilfe gesucht

  • Hallo zusammen.


    Im Moment arbeite ich an einem kleinen html parser, der auch schon recht gut funktioniert. Dazu verwende ich diese Regex


    Code
    <(.*?)>(.*?)</\\1>


    Nun kann ich mit dieser Regex nur <tag>contentent</tag> matchen. Ich probiere jetzt schon ein Weilchen herum, damit ich diese Fälle abdecken kann


    Code
    <tag>contentent</tag>
    <tag extra>contentent</tag>


    Vielleicht ist jemand hier, der mehr Regex Erfahrung hat als ich.


    Vielen Dank,
    ac

  • Zitat

    Original von Austrian Coder

    Code
    <tag>contentent</tag>
    <tag extra>contentent</tag>


    Wenn Du genau das erfassen willst:


    Code
    <([a-z]*?)>(.*?)</\\1>


    Attribute in den Tags gehen damit nicht...

  • Zitat

    und ein wenig mehr auf korrekte Syntax wert legst


    Für einen solchen Fall würde ich dies vorschlagen:


    Code
    <([a-zA-Z]\w+)(?:\s+([^>]+))?>


    Im Einzelnen:

    • ([a-zA-Z]\w+): Du suchst ein Wort, welches mit einem Buchstaben anfängt, danach aber auch Ziffern beinhalten darf. Das Wort hättest Du gerne in der Ergebnisliste (deshalb in Klammern)
    • (?: ... )? hiermit gruppiert man einen optionalen Suchbegriff, möchte diesen aber nicht in der Ergebnisliste haben
    • \s+([^>]+): Dein optionales Suchmuster fängt mit beliebig vielen Leerzeichen oder Tabs an. Alles was nicht aus Leerzeichen oder Tabs besteht hättest Du gerne in Deiner Ergebnisliste.


    Wenn Du damit aber wirklich Html oder auch Xml parsen möchtest, kommst Du schnell an den Punkt der Rekursion, der mit regulären Ausdrücken nicht flexibel genug verarbeitet werden kann (z.B. geschachtelte Tabellen).
    Wenn Du solche Muster verarbeiten möchtest, empfiehlt sich eine "Status-Maschine", d.h. Du suchst jeweils ein Tag, speicherst Dir den Namen und arbeitest weiter bis zum nächsten Tag. Wenn Du ein schließendes Tag findest, kannst Du das passende öffnende (in Deiner Liste der gelesenen Tags) suchen und entsprechend abschließen.


    Ein mögliches Suchmuster für eine solche Status-Maschine könnte so aussehen:

    Code
    <(/)?([a-zA-Z]\w+)(?:\s+(\w+)="([^"]+)")*>


    Bei diesem Muster würde der erste Ergebniswert ausdrücken, ob es ein öffnendes oder ein schließendes Tag ist, der 2. Ergebniswert beinhaltet den Tag-Bezeichner und nachfolgende Ergebniswerte beinhalten die Parameter jeweils als Pärchen.
    Selbstverfreilich kann dieses Muster nur XHtml bzw. XML parsen (und kann keine Texte, die ein Anführungszeichen enthalten).
    Für "altes" HTML müsstest Du die Wertzuweisung bei den Parametern noch optional machen.

    Ich bin verantwortlich für das, was ich schreibe, nicht für das, was Du verstehst!

  • Ohne jetzt allzuviel über die verwendete Sprache zu wissen. Warum nicht einen fertigen DOM-Parser nehmen? Die können meist auch regex und haben dabei auch keine Probs mit irgendwelchen namespaces oder Attributen.

  • Zitat

    So.. habe nun den Parser auf Basis von JParsec geschrieben


    Schade, dass Du nicht gleich geschrieben hast, dass Du Dich im Java-Umfeld bewegst.
    Bei der Apache-Group gibt es unter Jakarta/commons das Projekt "digester", welches mehr als nur einen Blick wert ist!


    Der endgültige Parser ist vielleicht nicht ganz so performant, wie Deine Lösung jetzt, aber das Schöne an digester ist, man kann sich seinen "parser" nach dem Baukastenprinzip zusammen bauen.

    Ich bin verantwortlich für das, was ich schreibe, nicht für das, was Du verstehst!

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!