Frage

Ich sehe jeden Tag Fragen, in denen man etwas analysiert oder aus einer HTML -Zeichenfolge extrahiert kann, und die erste Antwort/Kommentar lautet immer "Verwenden Sie Regex nicht, um HTML zu analysieren, damit Sie den Zorn nicht fühlen!" (Dieser letzte Teil wird manchmal weggelassen).

Dies ist ziemlich verwirrend für mich, ich dachte immer, dass im Allgemeinen der beste Weg, um eine komplizierte Zeichenfolge zu analysieren, darin besteht, einen regulären Ausdruck zu verwenden. Wie funktioniert ein HTML -Parser? Verwendet es nicht regelmäßige Ausdrücke, um zu analysieren?

Ein besonderes Argument für die Verwendung eines regulären Ausdrucks ist, dass es nicht immer eine Parsen -Alternative gibt (z. B. JavaScript, wobei Domdocument keine allgemein verfügbare Option ist). JQuery scheint beispielsweise mit einem Regex gut zu verwalten, um eine HTML -String in DOM -Knoten umzuwandeln.

Ich bin mir nicht sicher, ob dies eine echte Frage ist oder nicht, die ich beantwortet werden möchte und nicht wirklich ein Diskussionsthread sein möchte.

War es hilfreich?

Lösung

Normalerweise durch Verwendung eines Tokenisers. Der Entwurf Die HTML5 -Spezifikation hat einen umfangreichen Algorithmus zum Umgang mit "Real World HTML".

Andere Tipps

Wie funktioniert ein HTML -Parser? Verwendet es nicht regelmäßige Ausdrücke, um zu analysieren?

Nun, nein.

Wenn Sie in Ihrem Gehirn zu einer Theorie des Berechnungskurs zurückgreifen, wenn Sie einen oder einen Compiler -Kurs oder ähnliches belegen, erinnern Sie sich möglicherweise, dass es verschiedene Arten von Sprachen und Rechenmodellen gibt. Ich bin nicht qualifiziert, auf alle Details einzugehen, aber ich kann einige der wichtigsten Punkte mit Ihnen überprüfen.

Die einfachste Art von Sprache und Berechnung (für diese Zwecke) ist eine reguläre Sprache. Diese können mit regelmäßigen Ausdrücken erzeugt und mit endlichen Automaten erkannt werden. Grundsätzlich bedeutet dies, dass "Parsen" in diesen Sprachen "analysieren", aber nicht das Hilfsgedächtnis. HTML ist sicherlich keine reguläre Sprache. Wenn Sie darüber nachdenken, kann die Liste der Tags willkürlich zutiefst verschachtelt werden. Beispielsweise können Tabellen Tabellen enthalten, und jede Tabelle kann viele verschachtelte Tags enthalten. Mit regulären Ausdrücken können Sie möglicherweise ein Paar Tags auswählen, aber sicherlich nichts willkürlich verschachteltes.

Eine klassische einfache Sprache, die nicht regelmäßig ist, ist korrekt übereinstimmende Klammern. Versuchen Sie es, so wie Sie könnten, Sie werden niemals einen regelmäßigen Ausdruck (oder endlichen Automaten) erstellen können, der immer funktioniert. Sie benötigen Speicher, um die Nisttiefe im Auge zu behalten.

Eine Zustandsmaschine mit einem Stapel für den Speicher ist die nächste Stärke des Computermodells. Dies wird als Push-Down-Automaten bezeichnet und erkennt Sprachen, die durch kontextfreie Grammatiken generiert werden. Hier können wir korrekt übereinstimmende Klammern erkennen-ein Stapel ist das perfekte Speichermodell dafür.

Ist das gut genug für HTML? Traurigerweise Nein. Vielleicht für Super-Duper sorgfältig validierte XML, in dem sich alle Tags immer perfekt ausrichten. In realer HTML können Sie leicht Schnipsel finden wie <b><i>wow!</b></i>. Dies nistet offensichtlich nicht. Um es richtig zu analysieren, ist ein Stapel einfach nicht leistungsfähig genug.

Die nächste Berechnungsstufe sind Sprachen, die durch allgemeine Grammatiken erzeugt und von Turing -Maschinen erkannt werden. Dies wird allgemein als effektiv als das stärkste Rechenmodell anerkannt, das es gibt-eine Zustandsmaschine, mit Hilfspoten, deren Speicher überall geändert werden kann. Dies kann Programmiersprachen tun. Dies ist die Komplexität, auf der HTML lebt.

Um alles hier in einem Satz zusammenzufassen: Um allgemeine HTML zu analysieren, benötigen Sie eine echte Programmiersprache, keinen regulären Ausdruck.

HTML wird genauso analysiert wie andere Sprachen analysiert: Lexing und Parsen. Der Lexing -Schritt zerlegt den Strom einzelner Zeichen in sinnvolle Token. Der Parsing -Schritt stellt die Token mit Zuständen und Speicher in ein logisch kohärentes Dokument zusammen, auf das wir bewirken können.

Regelmäßige Ausdrücke sind nur eine Form von Parser. Ein ehrlicher HTML-Parser wird deutlich komplizierter sein als in Regexes verwendet werden können rekursive Abstammung, Vorhersage und mehrere andere Techniken, um den Text richtig zu interpretieren. Wenn Sie sich wirklich darauf einlassen möchten, können Sie sich auschecken Lex & Yacc und ähnliche Werkzeuge.

Das Verbot der Verwendung von Regexes für die HTML -Parsen sollte wahrscheinlich korrekter geschrieben werden: "Verwenden Sie nicht naiv Regelmäßige Ausdrücke, um HTML zu analysieren ... " (Damit Sie nicht den Zorn fühlen) "... und behandeln Sie die Ergebnisse mit Vorsicht." Für bestimmte spezifische Ziele ist ein Regex möglicherweise durchaus angemessen, aber Sie müssen sehr vorsichtig sein, um sich der Grenzen Ihres Regex und so vorsichtig wie angemessen für die Quelle des von Ihnen analysierten Textquelle zu bewusst (z. B. wenn es ist, z. B. wenn es ist Benutzereingabe, in der Tat sehr vorsichtig sein).

Das Parsen von HTML ist die Umwandlung eines linearen Textes in eine Baumstruktur. Regelmäßige Ausdrücke können im Allgemeinen nicht Baumstrukturen umgehen. Der reguläre Ausdruck, den Sie an jedem Punkt benötigen, um das nächste Token zu erhalten, ändert sich ständig. Sie können regelmäßige Ausdrücke in einem Parser verwenden, benötigen jedoch eine ganze Reihe von regulären Ausdrücken für jeden möglichen Analysezustand.

Wenn Sie eine 100% ige Lösung haben möchten: Sie müssen Ihren eigenen benutzerdefinierten Code schreiben, der das HTML-Zeichen für Charakter durchträgt, und Sie müssen eine enorme Menge Logik haben, um festzustellen, ob Sie den aktuellen Knoten stoppen und den Start haben sollten nächste.

Der Grund ist, dass dies gültig ist: HTML:

<ul>
<li>One
<li>Two
<li>Three
</ul>

Aber so ist das:

<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>

Wenn Sie mit "90% Lösung" in Ordnung sind: Wenn Sie einen XML -Parser zum Laden eines Dokuments verwenden, ist dies in Ordnung. Oder verwenden Sie Regex (obwohl der XML einfacher ist, wenn Sie dann den Inhalt beherrschen).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top