Ein Fehler , ich sehe Menschen , die über und immer wieder versucht , XML zu analysieren oder HTML mit einem regulären Ausdruck. Hier sind einige der Gründe, warum das Parsen von XML und HTML schwierig ist:
Die Benutzer möchten eine Datei als eine Folge von Zeilen behandeln, dies ist jedoch gültig:
<tag
attr="5"
/>
Die Leute wollen <oder <Tag als Anfang eines Tags behandeln, aber solche Dinge gibt es in freier Wildbahn:
<img src="imgtag.gif" alt="<img>" />
Menschen möchten häufig Start-Tags mit End-Tags abgleichen, aber XML und HTML ermöglichen es Tags, sich selbst zu enthalten (was herkömmliche Regexe überhaupt nicht verarbeiten können):
<span id="outer"><span id="inner">foo</span></span>
Menschen möchten häufig mit dem Inhalt eines Dokuments übereinstimmen (z. B. das berühmte Problem "Alle Telefonnummern auf einer bestimmten Seite finden"), aber die Daten können markiert sein (auch wenn sie beim Anzeigen normal erscheinen):
<span class="phonenum">(<span class="area code">703</span>)
<span class="prefix">348</span>-<span class="linenum">3020</span></span>
Kommentare können schlecht formatierte oder unvollständige Tags enthalten:
<a href="foo">foo</a>
<!-- FIXME:
<a href="
-->
<a href="bar">bar</a>
Welche anderen Fallstricke kennen Sie?
Antworten:
Hier ist ein lustiges, gültiges XML für Sie:
Und dieses kleine Bündel Freude ist gültiges HTML:
Ganz zu schweigen von der browserspezifischen Analyse für ungültige Konstrukte.
Viel Glück beim Regex!
EDIT (Jörg W Mittag): Hier ist ein weiteres schönes Stück wohlgeformten, gültigen HTML 4.01:
quelle
Tatsächlich
ist kein gültiges HTML und auch kein gültiges XML.
Es ist kein gültiges XML, da '<' und '>' keine gültigen Zeichen in Attributzeichenfolgen sind. Sie müssen mit den entsprechenden XML-Entitäten & lt; und & gt;
Es ist auch kein gültiges HTML, da das kurze Abschlussformular in HTML nicht zulässig ist (aber in XML und XHTML korrekt ist). Das 'img'-Tag ist auch ein implizit geschlossenes Tag gemäß der HTML 4.01-Spezifikation. Dies bedeutet, dass das manuelle Schließen tatsächlich falsch ist und dem zweimaligen Schließen eines anderen Tags entspricht.
Die richtige Version in HTML ist
und die richtige Version in XHTML und XML ist
Das folgende Beispiel ist ebenfalls ungültig
Dies ist auch kein gültiges HTML oder XML. Der Name des Tags muss direkt hinter dem '<' stehen, obwohl die Attribute und das schließende '>' beliebig sein können. Das gültige XML ist also tatsächlich
Und hier ist noch eine funkigere: Sie können entweder "oder" als Attribut-Anführungszeichen verwenden
Alle anderen Gründe, die veröffentlicht wurden, sind korrekt, aber das größte Problem beim Parsen von HTML ist, dass die Leute normalerweise nicht alle Syntaxregeln richtig verstehen. Die Tatsache, dass Ihr Browser Ihre Tag-Gruppe als HTML interpretiert, bedeutet nicht, dass Sie tatsächlich gültiges HTML geschrieben haben.
Bearbeiten: Und sogar stackoverflow.com stimmt mir hinsichtlich der Definition von gültig und ungültig zu. Ihr ungültiges XML / HTML wird nicht hervorgehoben, während meine korrigierte Version ist.
Grundsätzlich ist XML nicht dafür ausgelegt, mit regulären Ausdrücken analysiert zu werden. Es gibt aber auch keinen Grund dazu. Es gibt viele, viele XML-Parser für jede Sprache. Sie haben die Wahl zwischen SAX-Parsern, DOM-Parsern und Pull-Parsern. All dies ist garantiert viel schneller als das Parsen mit einem regulären Ausdruck, und Sie können dann coole Technologien wie XPath oder XSLT für den resultierenden DOM-Baum verwenden.
Meine Antwort lautet daher: Das Parsen von XML mit regulären Ausdrücken ist nicht nur schwierig, sondern auch eine schlechte Idee. Verwenden Sie einfach einen der Millionen vorhandenen XML-Parser und nutzen Sie alle erweiterten Funktionen von XML.
HTML ist einfach zu schwer, um es selbst zu analysieren. Erstens hat die legale Syntax viele kleine Feinheiten, die Sie vielleicht nicht kennen, und zweitens ist HTML in freier Wildbahn nur ein riesiger stinkender Haufen (Sie verstehen meine Abweichung). Es gibt eine Vielzahl von laxen Parser-Bibliotheken, die gute Arbeit im Umgang mit HTML wie Tag-Suppe leisten. Verwenden Sie einfach diese.
quelle
>
Zeichen ist vollkommen gültig in HTML stackoverflow.com/questions/94528/…Ich habe einen ganzen Blogeintrag zu diesem Thema geschrieben: Einschränkungen für reguläre Ausdrücke
Der Kern des Problems besteht darin, dass HTML und XML rekursive Strukturen sind, für deren korrekte Analyse Zählmechanismen erforderlich sind. Ein echter Regex kann nicht zählen. Sie müssen eine kontextfreie Grammatik haben, um zählen zu können.
Der vorige Absatz enthält eine leichte Einschränkung. Bestimmte Regex-Implementierungen unterstützen jetzt die Idee der Rekursion. Sobald Sie jedoch anfangen, Ihren Regex-Ausdrücken Rekursion hinzuzufügen, erweitern Sie wirklich die Grenzen und sollten einen Parser in Betracht ziehen.
quelle
Ein Problem, das nicht auf Ihrer Liste steht, ist, dass Attribute in beliebiger Reihenfolge angezeigt werden können. Wenn Ihr regulärer Ausdruck also nach einem Link mit dem href "foo" und der Klasse "bar" sucht, können sie in beliebiger Reihenfolge und mit einer beliebigen Anzahl anderer Attribute angezeigt werden Dinge zwischen ihnen.
quelle
Es hängt davon ab, was Sie unter "Parsen" verstehen. Im Allgemeinen kann XML nicht mit Regex analysiert werden, da die XML-Grammatik keineswegs regelmäßig ist. Um es einfach auszudrücken: Regexes können nicht zählen (Perl-Regexes können möglicherweise tatsächlich Dinge zählen), sodass Sie Open-Close-Tags nicht ausgleichen können.
quelle
Machen die Leute tatsächlich einen Fehler, wenn sie einen regulären Ausdruck verwenden, oder ist er einfach gut genug für die Aufgabe, die sie zu erfüllen versuchen?
Ich stimme voll und ganz zu, dass das Parsen von HTML und XML mit einem regulären Ausdruck nicht möglich ist, da andere Personen geantwortet haben.
Wenn Sie jedoch nicht HTML / XML analysieren möchten, sondern nur ein kleines Datenbit in einem "bekanntermaßen guten" Bit HTML / XML abrufen möchten, ist möglicherweise ein regulärer Ausdruck oder sogar ein noch einfacherer "Teilstring" ausreichend.
quelle
Normalerweise schreiben die Leute standardmäßig gierige Muster, was oft genug zu einem unüberlegten Durchführen führt. * Schlürfen großer Dateiblöcke in das größtmögliche <foo>. * </ Foo>.
quelle
.*?<
Sie können die Wiederholung nicht nur faul machen , sondern auch eine negierte Zeichenklasse wie verwenden[^<]*<
. (Haftungsausschluss: Offensichtlich ist das immer noch nicht narrensicher, worum es geht.)Ich bin versucht zu sagen "Erfinde das Rad nicht neu". Nur dass XML ein sehr, sehr komplexes Format ist. Vielleicht sollte ich sagen "Erfinde das Synchrotron nicht neu."
Vielleicht beginnt das richtige Klischee "wenn Sie nur einen Hammer haben ..." Sie wissen, wie man reguläre Ausdrücke verwendet, reguläre Ausdrücke können gut analysiert werden. Warum sollten Sie sich also die Mühe machen, eine XML-Analysebibliothek zu lernen?
Weil das Parsen von XML schwierig ist . Jeder Aufwand, den Sie sparen, wenn Sie nicht lernen müssen, eine XML-Analysebibliothek zu verwenden, wird durch die Menge an kreativer Arbeit und Fehlerbehebung, die Sie ausführen müssen, mehr als wettgemacht. Gehen Sie für sich selbst auf "XML-Bibliothek" und nutzen Sie die Arbeit eines anderen.
quelle
Ich glaube das Klassiker hat die Informationen, die Sie suchen. Sie finden den Punkt in einem der Kommentare dort:
Weitere Infos aus Wikipedia: Chomsky Hierarchy
quelle
Ich denke, die Probleme laufen auf Folgendes hinaus:
Die Regex ist fast immer falsch. Es gibt legitime Eingaben, die nicht korrekt übereinstimmen. Wenn Sie hart genug arbeiten, können Sie es zu 99% oder zu 99,999% korrekt machen, aber es ist fast unmöglich, es zu 100% korrekt zu machen, schon allein aufgrund der seltsamen Dinge, die XML durch die Verwendung von Entitäten zulässt.
Wenn der reguläre Ausdruck selbst für 0,00001% der Eingaben falsch ist, liegt ein Sicherheitsproblem vor, da jemand die eine Eingabe ermitteln kann, die Ihre Anwendung beschädigt.
Wenn der reguläre Ausdruck korrekt genug ist, um 99,99% der Fälle abzudecken, ist er völlig unlesbar und nicht wartbar.
Es ist sehr wahrscheinlich, dass ein Regex bei mittelgroßen Eingabedateien eine sehr schlechte Leistung erbringt. Meine allererste Begegnung mit XML bestand darin, ein Perl-Skript, das eingehende XML-Dokumente (fälschlicherweise) analysierte, durch einen geeigneten XML-Parser zu ersetzen. Wir haben nicht nur 300 Zeilen unlesbaren Codes durch 100 Zeilen ersetzt, die jeder verstehen konnte, sondern auch die Reaktionszeit der Benutzer verbessert von 10 Sekunden bis etwa 0,1 Sekunden.
quelle
Ich stimme dir nicht zu. Wenn Sie in Regex rekursiv verwenden, können Sie leicht offene und geschlossene Tags finden.
Hier habe ich ein Beispiel für Regex gezeigt, um Analysefehler von Beispielen in der ersten Nachricht zu vermeiden.
quelle
Ich habe eine vereinfachte Antwort auf dieses Problem hier . Obwohl die 100% -Marke nicht berücksichtigt wird, erkläre ich, wie es möglich ist, wenn Sie bereit sind, Vorverarbeitungsarbeiten durchzuführen.
quelle