Frage RegEx passt offene Tags an, mit Ausnahme von XHTML-eigenen Tags


Ich muss alle diese öffnenden Tags zusammenbringen:

<p>
<a href="foo">

Aber nicht diese:

<br />
<hr class="foo" />

Ich kam auf diese Idee und wollte sicherstellen, dass ich es richtig verstanden habe. Ich fange nur die a-z.

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

Ich glaube es sagt:

  • Finde ein weniger als dann
  • Finde (und fange) dann a-z ein oder mehrmals
  • Finde dann null oder mehr Leerzeichen
  • Finde ein beliebiges Zeichen null oder mehrmals, gierig, außer /, dann
  • Suchen Sie nach einem Größer-als-Wert

Habe ich das richtig? Und noch wichtiger, was denkst du?


1324
2017-09-27 04:01


Ursprung


Antworten:


Sie können [X] HTML mit Regex nicht analysieren. Weil HTML von Regex nicht analysiert werden kann. Regex ist kein Werkzeug, mit dem HTML korrekt analysiert werden kann. Da ich hier in HTML-und-Regex-Fragen schon so oft geantwortet habe, erlaubt dir die Verwendung von Regex nicht, HTML zu konsumieren. Reguläre Ausdrücke sind ein Werkzeug, das nicht ausreichend entwickelt ist, um die von HTML verwendeten Konstrukte zu verstehen. HTML ist keine reguläre Sprache und kann daher nicht von regulären Ausdrücken analysiert werden. Regex-Abfragen sind nicht in der Lage, HTML in seine sinnvollen Teile zu zerlegen. so oft, aber es kommt nicht zu mir. Selbst verbesserte unregelmäßige reguläre Ausdrücke, wie sie von Perl verwendet werden, sind nicht für die Analyse von HTML geeignet. Du wirst mich niemals zum Knacken bringen. HTML ist eine Sprache mit ausreichender Komplexität, die von regulären Ausdrücken nicht analysiert werden kann. Selbst Jon Skeet kann HTML nicht mit regulären Ausdrücken analysieren. Jedes Mal, wenn Sie versuchen, HTML mit regulären Ausdrücken zu parsen, weint das unheilige Kind das Blut von Jungfrauen, und russische Hacker züchten Ihre Webapp. Parsing HTML mit Regex beschwört verdorbene Seelen in das Reich der Lebenden. HTML und Regex gehören zusammen wie Liebe, Ehe und ritueller Kindermord. Das <center> kann nicht halten, es ist zu spät. Die Kraft von Regex und HTML zusammen in demselben konzeptuellen Raum wird deinen Verstand wie so viel wässriger Kitt zerstören. Wenn du HTML mit Regex parsierst, gibst du ihnen und ihren blasphemischen Wegen nach, die uns alle zu unmenschlicher Arbeit für den Einen verurteilen, dessen Name nicht in der Basic Multilingual Plane ausgedrückt werden kann, er kommt. HTML-plus-regexp verflüssigt die Energien des Empfindungsfähigen, während Sie beobachten, wie Ihre Psyche im Ansturm des Horrors verkümmert. Rege̿̔̉x-basierte HTML-Parser sind der Krebs, der StackOverflow tötet es ist zu spät, es ist zu spät, wir können nicht gerettet werden die Trangession eines Chiids stellt sicher, dass Regex alles lebende Gewebe verzehrt (außer HTML, das nicht wie vorher prophezeit werden kann) Lieber Herr, hilf uns, wie jemand diese Geißel überleben kann mit regex zum parsen HTML hat die Menschheit zu einer Ewigkeit von schrecklichen Folter- und Sicherheitslöchern gedrängt mit regex als Werkzeug zum Verarbeiten von HTML etabliert ein Breach zwischen dieser Welt und der fürchterliche Bereich von c͒ͪo͛ͫrrupt-Entitäten (wie SGML-Entitäten, aber korrupter) ein bloßer BlickSe der Welt der regEx-Parser für HTML werden insTanly transport a pdas Bewusstsein des Programmierers izu einem wOrld von unaufhörlichem Schreien kommt er, die Pest SLIthy Regex-Infektion wirdIch verschlinge dein HTML Parser, Anwendung und Existenz für alle Zeiten wie Visual Basic nur schlechter er kommt comes nicht fiGht he com̡e̶s, ̕h̵iS un̨ho͞ly radiańcé deAlle Enlightenment, HTML-Tags lea͠ki̧n͘g frûm ̡yo ͟ur Auge͢s̸ ̛l̕ik͏e liqUid pAin, das Lied der besonderen ErfahrungSsion Parsing wird extiNuish die Stimmen von mortal mann aus der spHier kann ich es sehen, kannst du sehen, dass es schön ister final snufFing of die Lüges des Menschen ALLES IST LOŚ͖̩͇̗̪̏̈T ALL I S LOST thUnd er kommts er c̶̮omes er comichs ter ichoder Permeates all MEIN FACE MEIN GESICHT ᵒh Gott no NO NOOO O NΘ Stopp ter ein * ̶͑̾̾ ̅ͫ͏̙̤g͇̫͛͆̾ͫ̑͆l͖͉̗̩̳̟̍ͫͥͨe̠̅s ͎a̧͈͖r̽̾̈́͒͑e nOt rè̑ͧ̌aͨl̘̝̙ͤ̾̆ ZA̡͊͠͝LGΌ ISͮ҉̯͈͕̹̘ TO͇̹̺Ɲ̴ȳ̳ TH̘͠ ͠P̯͍̭O̚ N̐Y̡ H̸̡̪̯ͨ͊̽̅̾Ȩ̬̩̾͛ͪ̈͘ ̶̧̨̹̭̯ͧ̾ͬC̷̙̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̖͊̒ͪͩͬ̚̚͜Ȇ̴̟̟͙̞ͩ͌͝S̨̥̫͎̭ͯ̿̔


Haben Sie versucht, stattdessen einen XML-Parser zu verwenden?


Anmerkung des Moderators

Dieser Beitrag ist gesperrt, um unangemessene Änderungen an seinem Inhalt zu verhindern. Der Beitrag sieht genau so aus, wie er aussehen soll - mit seinem Inhalt gibt es keine Probleme. Bitte kennzeichnen Sie es nicht für unsere Aufmerksamkeit.


4422



Es stimmt zwar, dass Regexes parsen willkürlich HTML ist wie ein Anfänger zu fragen, ein Betriebssystem zu schreiben, es ist manchmal angemessen, ein zu analysieren begrenzt, bekannt Satz von HTML.

Wenn Sie eine kleine Menge von HTML-Seiten haben, von denen Sie Daten abkratzen und dann in eine Datenbank stopfen wollen, könnten Regexes gut funktionieren. Zum Beispiel wollte ich kürzlich die Namen, Parteien und Distrikte der australischen Bundesvertreter, die ich von der Website des Parlaments bekommen habe. Dies war ein begrenzter, einmaliger Job.

Regexes funktionierten gut für mich und waren sehr schnell einzurichten.


2915



Ich denke der Fehler hier ist, dass HTML ein ist Chomsky Typ 2 Grammatik (kontextfreie Grammatik) und RegEx ist ein Chomsky Typ 3 Grammatik (reguläre Grammatik). Da eine Grammatik vom Typ 2 wesentlich komplexer ist als eine Grammatik vom Typ 3 (siehe Chomsky-Hierarchie), du kannst unmöglich diese Arbeit machen. Aber viele werden es versuchen, andere werden Erfolg haben und andere werden den Fehler finden und dich völlig durcheinander bringen.


1799



Hör nicht auf diese Jungs. Du tatsächlich kann Analysiere kontextfreie Grammatiken mit Regex, wenn du die Aufgabe in kleinere Teile aufteilst. Sie können das korrekte Muster mit einem Skript generieren, das jede der folgenden Reihenfolge ausführt:

  1. Lösen Sie das Halteproblem.
  2. Quadrieren Sie einen Kreis (simulieren Sie dazu die Methode "Lineal und Zirkel").
  3. Erarbeiten Sie das Problem des reisenden Verkäufers in O (log n). Es muss schnell sein oder der Generator wird hängen.
  4. Das Muster wird ziemlich groß sein, also stellen Sie sicher, dass Sie einen Algorithmus haben, der zufällige Daten verlustfrei komprimiert.
  5. Fast da - teile das Ganze einfach durch Null. Kinderleicht.

Ich habe den letzten Teil noch nicht herausgefunden, aber ich weiß, dass ich nah dran bin. Mein Code wirft weiter CthulhuRlyehWgahnaglFhtagnExceptions in letzter Zeit, also werde ich es nach VB 6 portieren und benutzen On Error Resume Next. Ich werde mit dem Code aktualisieren, sobald ich diese seltsame Tür untersuche, die gerade in der Wand geöffnet hat. Hmm.

P.S. Pierre de Fermat hat auch herausgefunden, wie es geht, aber der Rand, in den er schrieb, war nicht groß genug für den Code.


1167



Haftungsausschluss: Verwenden Sie einen Parser, wenn Sie die Option haben. Das gesagt...

Dies ist die Regex, die ich (!) Verwende, um HTML-Tags zu finden:

<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>

Es mag nicht perfekt sein, aber ich habe diesen Code durch eine Menge von HTML. Beachten Sie, dass es sogar seltsame Dinge wie <a name="badgenerator"">, die im Internet angezeigt werden.

Ich schätze, damit es nicht mit eigenständigen Tags übereinstimmt, die Sie verwenden möchten KobiNegativer Blick hinterher:

<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+(?<!/\s*)>

oder kombinieren Sie einfach, wenn und wenn nicht.

Zu den Downvotern: Dies ist Arbeitscode von einem tatsächlichen Produkt. Ich bezweifle, dass jemand, der diese Seite liest, den Eindruck bekommt, dass es sozial akzeptabel ist, Regexes in HTML zu verwenden.

Vorbehalt: Ich sollte beachten, dass diese Regex immer noch in der Anwesenheit von CDATA Blöcken, Kommentaren und Skript- und Stilelementen zusammenbricht. Eine gute Nachricht ist, dass Sie diejenigen loswerden können, die eine Regex verwenden ...


1016



Es gibt Leute, die dir sagen werden, dass die Erde rund ist (oder vielleicht, dass die Erde ein abgeplatteter Sphäroid ist, wenn sie seltsame Wörter benutzen wollen). Sie lügen.

Es gibt Leute, die Ihnen sagen, dass reguläre Ausdrücke nicht rekursiv sein sollten. Sie beschränken dich. Sie müssen dich unterwerfen, und sie tun es, indem sie dich in Unwissenheit halten.

Sie können in ihrer Realität leben oder die rote Pille nehmen.

Wie Lord Marshal (ist er ein Verwandter der Marshal .NET-Klasse?), Habe ich das gesehen Unterversessenheit Stack Based Regex-Verse und zurückgegeben mit Kräfte Wissen, das du dir nicht vorstellen kannst. Ja, ich glaube, es gab ein oder zwei Alte, die sie beschützten, aber sie schauten auf dem Fernseher Fußball, also war es nicht schwer.

Ich denke, der XML-Fall ist ziemlich einfach. Die RegEx (in der .NET-Syntax), deflationiert und in base64 codiert, um es für Ihren schwachen Verstand leichter verständlich zu machen, sollte in etwa so aussehen:

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
+r/vD34mUADO1P4/AQAA//8=

Die zu setzenden Optionen sind RegexOptions.ExplicitCapture. Die Erfassungsgruppe, nach der Sie suchen, ist ELEMENTNAME. Wenn die Erfassungsgruppe ERROR ist nicht leer, dann gab es einen Parsing-Fehler und die Regex gestoppt.

Wenn Sie Probleme haben, es in eine menschenlesbare Regex umzuwandeln, sollte dies helfen:

static string FromBase64(string str)
{
    byte[] byteArray = Convert.FromBase64String(str);

    using (var msIn = new MemoryStream(byteArray))
    using (var msOut = new MemoryStream()) {
        using (var ds = new DeflateStream(msIn, CompressionMode.Decompress)) {
            ds.CopyTo(msOut);
        }

        return Encoding.UTF8.GetString(msOut.ToArray());
    }
}

Wenn du unsicher bist, nein, ich mache keine Witze (aber vielleicht lüge ich). Es wird klappen. Ich habe Tonnen von Komponententests gebaut, um es zu testen, und ich habe sogar (teilweise) die Konformitätstests. Es ist ein Tokenizer, kein vollwertiger Parser, daher teilt es nur die XML in seine Komponententoken. Es wird keine DTDs analysieren / integrieren.

Oh ... wenn Sie den Quellcode der Regex wollen, mit einigen Hilfsmethoden:

Regex, um ein XML zu tokenisieren oder die volle Ebene Regex 


452



In der Shell können Sie analysieren HTML mit:

  • sed obwohl:

    1. Turing.sed
    2. HTML-Parser schreiben (Hausaufgabe)
    3. ???
    4. Profitieren!
  • hxselect von html-xml-utils Paket

  • vim/ex (was leicht kann Zwischen HTML-Tags springen), beispielsweise:

    • Entfernen von Style-Tags mit innerem Code:

      $ curl -s http://example.com/ | ex -s +'/<style.*/norm nvatd' +%p -cq! /dev/stdin
      
  • grep, beispielsweise:

    • Extrahieren der äußeren HTML von H1:

      $ curl -s http://example.com/ | grep -o '<h1>.*</h1>'
      <h1>Example Domain</h1>
      
    • den Körper extrahieren:

      $ curl -s http://example.com/ | tr '\n' ' ' | grep -o '<body>.*</body>'
      <body> <div> <h1>Example Domain</h1> ...
      
  • html2text zum Klartext-Parsen:

  • verwenden xpath (XML::XPath Perl-Modul), siehe Beispiel hier

  • Perl oder Python (siehe @Gilles Beispiel)

  • um mehrere Dateien gleichzeitig zu analysieren, siehe: Wie hundert hundert HTML-Quellcode-Dateien in der Shell analysieren?


Related (warum sollten Sie keine Regex-Übereinstimmung verwenden):


285



Ich stimme zu, dass das richtige Werkzeug zum Parsen von XML und vor allem HTML ist ein Parser und keine Engine für reguläre Ausdrücke. Wie jedoch andere bereits festgestellt haben, ist die Verwendung eines Regex manchmal schneller, einfacher und erledigt die Arbeit, wenn Sie das Datenformat kennen.

Microsoft hat tatsächlich einen Abschnitt von Best Practices für reguläre Ausdrücke in .NET Framework und spricht speziell darüber Berücksichtigen Sie die Eingabequelle.

Reguläre Ausdrücke haben Einschränkungen, aber haben Sie Folgendes berücksichtigt?

Das .NET-Framework ist einzigartig, wenn es um reguläre Ausdrücke geht, die es unterstützt Bilanzkreisdefinitionen.

Aus diesem Grund glaube ich, dass Sie XML mit regulären Ausdrücken analysieren können. Beachten Sie jedoch, dass es muss gültiges XML sein (Browser verzeihen HTML sehr und erlauben eine schlechte XML-Syntax in HTML). Dies ist möglich, da die "Balancing Group Definition" es der Engine für reguläre Ausdrücke ermöglicht, als PDA zu agieren.

Zitat aus dem oben genannten Artikel 1:

Reguläre Expression-Engine

Wie oben beschrieben, können richtig ausgewogene Konstrukte nicht beschrieben werden   ein regulärer Ausdruck. Die .NET-Engine für reguläre Ausdrücke   stellt einige Konstrukte bereit, die ausgeglichene Konstrukte erlauben   anerkannt.

  • (?<group>) - schiebt das erfasste Ergebnis auf den Capture-Stack mit   die Namensgruppe.
  • (?<-group>) - knallt die oberste Aufnahme mit der Namensgruppe ab   Stapel erfassen
  • (?(group)yes|no) - stimmt mit dem Ja-Teil überein, wenn eine Gruppe existiert   mit der Namensgruppe stimmt sonst kein Teil überein.

Diese Konstrukte ermöglichen, dass ein regulärer .NET-Ausdruck emuliert   eingeschränkter PDA, indem im Wesentlichen einfache Versionen des Stapels zugelassen werden   Operationen: drücken, pop und leer. Die einfachen Operationen sind ziemlich viel   entsprechend inkrementieren, dekrementieren und mit Null vergleichen.   Dies ermöglicht der .NET-Engine für reguläre Ausdrücke, a zu erkennen   Teilmenge der kontextfreien Sprachen, insbesondere diejenigen, die nur   benötigen einen einfachen Zähler. Dies wiederum ermöglicht das Nicht-Traditionelle   .NET reguläre Ausdrücke zu erkennen, richtig ausgewogene   konstruiert.

Betrachten Sie den folgenden regulären Ausdruck:

(?=<ul\s+id="matchMe"\s+type="square"\s*>)
(?>
   <!-- .*? -->                  |
   <[^>]*/>                      |
   (?<opentag><(?!/)[^>]*[^/]>)  |
   (?<-opentag></[^>]*[^/]>)     |
   [^<>]*
)*
(?(opentag)(?!))

Benutze die Flaggen:

  • Einzelne Zeile
  • IgnorePatternWhitespace (nicht notwendig, wenn Sie Regex reduzieren und alle Leerzeichen entfernen)
  • IgnoreCase (nicht notwendig)

Regulärer Ausdruck erklärt (Inline)

(?=<ul\s+id="matchMe"\s+type="square"\s*>) # match start with <ul id="matchMe"...
(?>                                        # atomic group / don't backtrack (faster)
   <!-- .*? -->                 |          # match xml / html comment
   <[^>]*/>                     |          # self closing tag
   (?<opentag><(?!/)[^>]*[^/]>) |          # push opening xml tag
   (?<-opentag></[^>]*[^/]>)    |          # pop closing xml tag
   [^<>]*                                  # something between tags
)*                                         # match as many xml tags as possible
(?(opentag)(?!))                           # ensure no 'opentag' groups are on stack

Sie können dies an versuchen Ein besserer .NET Regular Expression Tester.

Ich benutzte die Beispielquelle von:

<html>
<body>
<div>
   <br />
   <ul id="matchMe" type="square">
      <li>stuff...</li>
      <li>more stuff</li>
      <li>
          <div>
               <span>still more</span>
               <ul>
                    <li>Another &gt;ul&lt;, oh my!</li>
                    <li>...</li>
               </ul>
          </div>
      </li>
   </ul>
</div>
</body>
</html>

Dies hat das Spiel gefunden:

   <ul id="matchMe" type="square">
      <li>stuff...</li>
      <li>more stuff</li>
      <li>
          <div>
               <span>still more</span>
               <ul>
                    <li>Another &gt;ul&lt;, oh my!</li>
                    <li>...</li>
               </ul>
          </div>
      </li>
   </ul>

obwohl es tatsächlich so herauskam:

<ul id="matchMe" type="square">           <li>stuff...</li>           <li>more stuff</li>           <li>               <div>                    <span>still more</span>                    <ul>                         <li>Another &gt;ul&lt;, oh my!</li>                         <li>...</li>                    </ul>               </div>           </li>        </ul>

Zu guter Letzt habe ich Jeff Atwoods Artikel sehr genossen: Parsing Html Der Cthulhu Weg. Lustig genug, zitiert es die Antwort auf diese Frage, die derzeit über 4k Stimmen hat.


261



Ich schlage vor, zu verwenden QueryPfad zum Parsen von XML und HTML in PHP. Es ist im Grunde genommen die gleiche Syntax wie jQuery, nur auf der Serverseite.


255



Während die Antworten, dass Sie HTML mit Regexes nicht analysieren können, korrekt sind, gelten sie hier nicht. Das OP möchte nur ein HTML-Tag mit Regexen analysieren, und dies kann mit einem regulären Ausdruck geschehen.

Die vorgeschlagene Regex ist jedoch falsch:

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

Wenn Sie etwas zum Regex hinzufügen, können Sie durch Rückverfolgung gezwungen werden, dumme Dinge wie <a >>, [^/] ist zu freizügig. Beachten Sie auch das <space>*[^/]* ist überflüssig, weil die [^/]* kann auch Leerzeichen zuordnen.

Mein Vorschlag wäre

<([a-z]+)[^>]*(?<!/)>

Woher (?<! ... ) ist (in Perl regexes) der negative Look-Behind. Es liest "a <, dann ein Wort, dann alles was nicht> ist, wobei das letzte nicht ein / ist, gefolgt von>".

Beachten Sie, dass dies Dinge wie erlaubt <a/ > (Genau wie die ursprüngliche Regex), also wenn Sie etwas restriktiveres wollen, müssen Sie eine Regex erstellen, um Attributpaare zu finden, die durch Leerzeichen getrennt sind.


212