Sie können [X] HTML nicht mit Regex analysieren. Weil HTML nicht durch Regex analysiert werden kann. Regex ist kein Tool, mit dem HTML korrekt analysiert werden kann. Wie ich hier schon so oft in HTML- und Regex-Fragen beantwortet habe, können Sie mit der Verwendung von Regex kein HTML verwenden. Reguläre Ausdrücke sind ein Werkzeug, das nicht ausgereift genug ist, um die von HTML verwendeten Konstrukte zu verstehen. HTML ist keine reguläre Sprache und kann daher nicht durch reguläre Ausdrücke analysiert werden. Regex-Abfragen sind nicht in der Lage, HTML in seine sinnvollen Teile zu zerlegen. so oft, aber es geht mir nicht auf die Nerven. Selbst verbesserte unregelmäßige reguläre Ausdrücke, wie sie von Perl verwendet werden, sind nicht in der Lage, HTML zu analysieren. Du wirst mich niemals zum Knacken bringen. HTML ist eine Sprache von ausreichender Komplexität, die nicht durch reguläre Ausdrücke 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 analysieren, weint das unheilige Kind das Blut von Jungfrauen, und russische Hacker pwn Ihre Webapp. Das Parsen von HTML mit Regex-Beschwörungen befleckte Seelen in das Reich der Lebenden. HTML und Regex gehören zusammen wie Liebe, Ehe und ritueller Kindsmord. Das <Center> kann es nicht halten, es ist zu spät. Die Kraft von Regex und HTML zusammen im selben konzeptuellen Raum wird Ihren Geist zerstören wie so viel wässriger Kitt. Wenn Sie HTML mit Regex analysieren, geben Sie ihnen und ihren blasphemischen Methoden nach, die uns alle zur unmenschlichen Arbeit für denjenigen verurteilen, dessen Name in der mehrsprachigen Grundebene nicht ausgedrückt werden kann. HTML-plus-Regexp wird die Nerven des Lebewesens verflüssigen, während Sie beobachten, wie Ihre Psyche im Ansturm des Grauens verdorrt.Es ist zu spät. Es ist zu spät. Wir können nicht gerettet werden. Die Trangession eines Kindes stellt sicher, dass Regex das gesamte lebende Gewebe verbraucht (mit Ausnahme von HTML, das, wie zuvor prophezeit, nicht). Sehr geehrter Herr, helfen Sie uns, wie jemand diese Geißel mit Regex zum Parsen überleben kann HTML hat die Menschheit zu einer Ewigkeit der Angst Folter und Sicherheitslücken verurteilt mit Rege x als Instrument zum Prozess HTML stellt eine Brea ch zwischen dieser Welt und der Furcht Reich der korrupten Entitäten (wie SGML Entitäten, sondern mehr korrupt) einem bloßen glimp se die Welt der reg ex - Parser für HTML wird ins tantly Transport ap Bewusstsein rogrammer i nto aw orl d unaufhörlichen schreien, er kommt, Die pestilent sl Ithy regex-Infektion wil l Verschlingen Ihre HT ML - Parser, Anwendung und Existenz für alle Zeiten wie Visual Basic nur noch schlimmer er kommt er com es nicht fi ght h e kommt, HALLO s unheilige Radiance de stro҉ying , alle AUFKLäRUNG HTML - Tags Undichte fr̶ǫm Ih re Augen wie liq uid p ain, das Lied von regelmäßig exp Re ssion Parsing wird extI nguish die Stimmen von mor tal Mann aus dem sp hier kann ich sehen , es können Sie sehen , es ist schön t er f inal snuf
Fing o f die Lüge s of Man ist alles verloren A LL I SLOST th e PONY er kommt s er CoM es ihn zusammen mir s t er mich oder Permeats es al l MY FAC E MEIN GESICHT ᵒh Gott n o NO noo O ON Θ Anschlag t er ein * ̶͑̾̾ gl ES ͎a̧͈͖r̽̾̈́͒͑e
n ot rè̑ͧ̌aͨl̘̝̙̃ͤ͂̾̆ ZA̡͊͠͝LGΌ ISͮ̂҉̯͈͕̹̘̱ T O͇̹̺ͅƝ̴ȳ̳ 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 - es gibt keine Probleme mit seinem Inhalt. Bitte kennzeichnen Sie es nicht für unsere Aufmerksamkeit.
Während beliebiges HTML mit nur einem regulären Ausdruck unmöglich ist, ist es manchmal angebracht, sie zum Parsen eines begrenzten, bekannten Satzes von HTML zu verwenden.
Wenn Sie eine kleine Gruppe von HTML-Seiten haben, von denen Sie Daten kratzen und dann in eine Datenbank einfügen möchten, funktionieren reguläre Ausdrücke möglicherweise einwandfrei. Zum Beispiel wollte ich kürzlich die Namen, Parteien und Bezirke der australischen Bundesvertreter erfahren, die ich von der Website des Parlaments erhalten habe. Dies war ein begrenzter, einmaliger Job.
Regexes funktionierte gut für mich und war sehr schnell einzurichten.
quelle
&foo;
Codierungen undCDATA
Abschnitten wechseln? Verwenden Sie einen HTML-Minifier, um alle Leerzeichen in Ihrem Dokument zu entfernen, die der Browser nicht rendert? Ein XML-Parser kümmert sich nicht darum, ebenso wenig wie eine gut geschriebene XPath-Anweisung. Ein Regex-basierter "Parser" andererseits ...<font>
usw.: Keine Klassen oder IDs zur Navigation im DOM. Nachdem ich den ganzen Tag mit dem "richtigen" Ansatz gekämpft hatte, wechselte ich schließlich zu einer Regex-Lösung und ließ sie in einer Stunde funktionieren.Ich denke, der Fehler hier ist, dass HTML eine Chomsky-Typ-2-Grammatik (kontextfreie Grammatik) und RegEx eine Chomsky-Typ-3-Grammatik (reguläre Grammatik) ist . Da eine Grammatik vom Typ 2 grundsätzlich komplexer ist als eine Grammatik vom Typ 3 (siehe Chomsky-Hierarchie ), ist es mathematisch unmöglich , XML mit RegEx zu analysieren.
Aber viele werden es versuchen, einige werden sogar Erfolg beanspruchen - aber bis andere den Fehler finden und dich total durcheinander bringen.
quelle
A -> s A e
). (X) HTML ist nicht diese Eigenschaft hat in einem Start - Tag: ein Start - Tag enthalten kann Tags keine anderen Anfang. Die Teilmenge, die das OP zu analysieren versucht, ist keine CFG.Hör nicht auf diese Jungs. Sie können kontextfreie Grammatiken mit Regex vollständig analysieren, wenn Sie die Aufgabe in kleinere Teile aufteilen. Sie können das richtige Muster mit einem Skript generieren, das diese in der folgenden Reihenfolge ausführt:
Ich habe den letzten Teil selbst noch nicht ganz beendet, aber ich weiß, dass ich näher komme. Es wirft
CthulhuRlyehWgahnaglFhtagnException
aus irgendeinem Grund immer wieder s, also werde ich es auf VB 6 portieren und verwendenOn Error Resume Next
. Ich werde mit dem Code aktualisieren, sobald ich diese seltsame Tür untersucht habe, die sich gerade in der Wand geöffnet hat. Hmm.PS Pierre de Fermat fand auch heraus, wie es geht, aber der Rand, in den er schrieb, war nicht groß genug für den Code.
quelle
Haftungsausschluss : Verwenden Sie einen Parser, wenn Sie die Option haben. Das gesagt...
Dies ist der reguläre Ausdruck, den ich (!) Zum Abgleichen von HTML-Tags verwende:
Es mag nicht perfekt sein, aber ich habe diesen Code durch viel HTML ausgeführt. Beachten Sie, dass es sogar seltsame Dinge auffängt
<a name="badgenerator"">
, die im Web auftauchen.Ich denke, damit es nicht zu eigenständigen Tags passt, möchten Sie entweder Kobis negativen Look-Behind verwenden:
oder einfach kombinieren, wenn und wenn nicht.
An Downvoter: Dies ist Arbeitscode von einem tatsächlichen Produkt. Ich bezweifle, dass jemand, der diese Seite liest, den Eindruck bekommt, dass es gesellschaftlich akzeptabel ist, Regexes in HTML zu verwenden.
Vorsichtsmaßnahme : Ich sollte beachten, dass dieser reguläre Ausdruck bei Vorhandensein von CDATA-Blöcken, Kommentaren sowie Skript- und Stilelementen immer noch zusammenbricht. Eine gute Nachricht ist, dass Sie diese mit einem regulären Ausdruck loswerden können ...
quelle
<!doctype html><title><</title>
. Einfache'<!doctype html><title><</title>'.match(/<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>/g)
Rückgabe["<!doctype html>", "<title>", "<</title>"]
während sollte["<title>", "</title>"]
.Es gibt Leute, die Ihnen sagen, dass die Erde rund ist (oder dass die Erde ein abgeflachter Sphäroid ist, wenn sie seltsame Wörter verwenden möchten). Sie lügen.
Es gibt Leute, die Ihnen sagen, dass reguläre Ausdrücke nicht rekursiv sein sollten. Sie begrenzen 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 (er ist ein Verwandter der Klasse Marshal .NET?), Ich habe das gesehen
UnderverseStapel Based Regex-Verse und mit zurückKräfteWissen Sie können sich nicht vorstellen. Ja, ich glaube, es gab ein oder zwei Alte, die sie beschützten, aber sie sahen Fußball im Fernsehen, also war es nicht schwierig.Ich denke, der XML-Fall ist recht einfach. Die RegEx (in der .NET-Syntax), die in base64 deflationiert und codiert ist, um das Verständnis für Ihren schwachen Verstand zu erleichtern, sollte ungefähr so aussehen:
Die einzustellenden Optionen sind
RegexOptions.ExplicitCapture
. Die von Ihnen gesuchte Erfassungsgruppe istELEMENTNAME
. Wenn die ErfassungsgruppeERROR
nicht leer ist, ist ein Analysefehler aufgetreten und der Regex wurde gestoppt.Wenn Sie Probleme haben, es in einen für Menschen lesbaren regulären Ausdruck umzuwandeln, sollte dies helfen:
Wenn Sie sich nicht sicher sind, 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 (einen Teil) der Konformitätstests verwendet . Es ist ein Tokenizer, kein ausgewachsener Parser, daher wird das XML nur in seine Komponententoken aufgeteilt. DTDs werden nicht analysiert / integriert.
Oh ... wenn Sie den Quellcode des regulären Ausdrucks mit einigen Hilfsmethoden möchten:
Regex zum Tokenisieren einer XML-Datei oder des vollständigen einfachen Regex
quelle
In der Shell können Sie HTML mit sed analysieren :
Verwandte (warum Sie Regex Match nicht verwenden sollten):
quelle
Ich bin damit einverstanden, dass das richtige Tool zum Parsen von XML und insbesondere HTML ein Parser und keine Engine für reguläre Ausdrücke ist. Wie andere bereits betont haben, ist die Verwendung eines regulären Ausdrucks manchmal schneller, einfacher und erledigt die Aufgabe, wenn Sie das Datenformat kennen.
Microsoft hat tatsächlich einen Abschnitt mit Best Practices für reguläre Ausdrücke in .NET Framework und spricht speziell über die Berücksichtigung der Eingabequelle .
Reguläre Ausdrücke haben zwar Einschränkungen, aber haben Sie Folgendes berücksichtigt?
Das .NET Framework ist einzigartig, wenn es um reguläre Ausdrücke geht, da es Ausgleichsgruppendefinitionen unterstützt .
Aus diesem Grund glaube ich, dass Sie XML mit regulären Ausdrücken analysieren können. Beachten Sie jedoch, dass es sich um gültiges XML handeln muss ( 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 fungieren.
Zitat aus Artikel 1 oben zitiert:
Betrachten Sie den folgenden regulären Ausdruck:
Verwenden Sie die Flags:
Regulärer Ausdruck erklärt (inline)
Sie können dies bei A Better .NET Regular Expression Tester versuchen .
Ich habe die Beispielquelle verwendet von:
Dies fand die Übereinstimmung:
obwohl es tatsächlich so herauskam:
Zuletzt hat mir Jeff Atwoods Artikel: Parsing Html The Cthulhu Way sehr gut gefallen . Komischerweise wird die Antwort auf diese Frage zitiert, die derzeit über 4.000 Stimmen hat.
quelle
System.Text
ist nicht Teil von C #. Es ist Teil von .NET.(?=<ul\s*id="matchMe"\s*type="square"\s*>) # match start with <ul id="matchMe"...
) sollte zwischen "<ul" und "id"\s+
nicht stehen\s*
, es sei denn, Sie möchten, dass es mit <ulid = ... übereinstimmt;)\s+
statt\s*
.<img src="images/pic.jpg" />
/
irgendwo etwas befand, das für Ihr<img src="images/pic.jpg" />
HTML fehlschlug .Ich schlage vor, QueryPath zum Parsen von XML und HTML in PHP zu verwenden. Es ist im Grunde die gleiche Syntax wie jQuery, nur auf der Serverseite.
quelle
Die Antworten, dass Sie HTML nicht mit regulären Ausdrücken analysieren können, sind zwar korrekt, gelten hier jedoch nicht. Das OP möchte nur ein HTML-Tag mit regulären Ausdrücken analysieren, und das kann mit einem regulären Ausdruck erfolgen.
Der vorgeschlagene reguläre Ausdruck ist jedoch falsch:
Wenn Sie etwas zu dem regulären Ausdruck hinzufügen, indem Rückzieher kann es gezwungen sein , dumme Sachen zu passen wie
<a >>
,[^/]
zu tolerant ist. Beachten Sie auch, dass dies<space>*[^/]*
redundant ist, da die[^/]*
auch Leerzeichen entsprechen können.Mein Vorschlag wäre
Wo
(?<! ... )
ist (in Perl-Regexen) der negative Rückblick. Es lautet "a <, dann ein Wort, dann alles, was nicht a> ist, von denen das letzte möglicherweise kein / ist, gefolgt von>".Beachten Sie, dass dies Dinge wie
<a/ >
(genau wie der ursprüngliche reguläre Ausdruck) zulässt. Wenn Sie also etwas restriktiveres wünschen, müssen Sie einen regulären Ausdruck erstellen, der mit durch Leerzeichen getrennten Attributpaaren übereinstimmt.quelle
>
Zeichen enthält . Ich stimme zu, was OP mit einem regulären Ausdruck vorschlagen kann , aber der hier vorgestellte ist viel zu simpel.Versuchen:
Es ist ähnlich wie deins, aber das letzte
>
darf nicht nach einem Schrägstrich sein und akzeptiert auchh1
.quelle
>
Symbol ordnungsgemäß in & gt; maskiert ist.>
ist in einem Attributwert gültig. In der Serialisierung "Canonical XML" dürfen Sie diese nicht verwenden>
. (Was nicht ganz relevant ist, außer um zu betonen, dass>
in einem Attribut Wert überhaupt keine ungewöhnliche Sache ist.)<div title="this tag is a <div></div>">hello</div>
Sun Tzu, ein alter chinesischer Stratege, General und Philosoph, sagte:
In diesem Fall ist Ihr Feind HTML und Sie sind entweder Sie selbst oder Regex. Sie könnten sogar Perl mit unregelmäßigem Regex sein. HTML kennen. Sich selbst kennen.
Ich habe ein Haiku verfasst, das die Natur von HTML beschreibt.
Ich habe auch ein Haiku verfasst, das die Natur von Regex in Perl beschreibt.
quelle
Ausgabe:
Definieren Sie einfach die Namen der Elementknoten, die sich selbst schließen, laden Sie die gesamte HTML-Zeichenfolge in eine DOM-Bibliothek, greifen Sie auf alle Elemente zu, durchlaufen Sie sie und filtern Sie diejenigen heraus, die sich nicht selbst schließen, und bearbeiten Sie sie.
Ich bin mir sicher, dass Sie bereits wissen, dass Sie Regex für diesen Zweck nicht verwenden sollten.
quelle
NS
und geben Sie den Namespace an.Ich weiß nicht, wie genau Sie dies benötigen, aber wenn Sie auch .NET verwenden, können Sie dann nicht das HTML Agility Pack verwenden ?
Auszug:
quelle
Sie möchten, dass dem ersten
>
kein a vorangestellt wird/
. Einzelheiten dazu finden Sie hier . Es wird als negatives Aussehen bezeichnet.Eine naive Implementierung davon wird jedoch
<bar/></foo>
in diesem Beispieldokument übereinstimmenKönnen Sie etwas mehr Informationen zu dem Problem geben, das Sie lösen möchten? Durchlaufen Sie Tags programmgesteuert?
quelle
Das W3C erklärt das Parsen in einer Pseudo-Regexp-Form:
W3C Link
Folgen Sie den var-Links für
QName
,S
undAttribute
, um ein klareres Bild zu erhalten.Basierend darauf können Sie einen ziemlich guten regulären Ausdruck erstellen, um Dinge wie das Entfernen von Tags zu handhaben.
quelle
Wenn Sie dies für PHP benötigen:
Die PHP-DOM- Funktionen funktionieren nur dann ordnungsgemäß, wenn XML ordnungsgemäß formatiert ist. Egal wie viel besser sie für den Rest der Menschheit sind.
simplehtmldom ist gut, aber ich fand es ein bisschen fehlerhaft und es ist ziemlich speicherlastig [Wird auf großen Seiten abstürzen.]
Ich habe Querypath noch nie verwendet , kann daher seine Nützlichkeit nicht kommentieren.
Ein weiterer Versuch ist mein DOMParser, der sehr ressourcenschonend ist und den ich seit einiger Zeit gerne benutze. Einfach zu lernen und leistungsstark.
Für Python und Java wurden ähnliche Links veröffentlicht.
Für die Downvoter - Ich habe meine Klasse erst geschrieben, als sich herausstellte, dass die XML-Parser der tatsächlichen Verwendung nicht standhalten konnten. Religiöses Downvoting verhindert nur, dass nützliche Antworten veröffentlicht werden - halten Sie die Dinge bitte im Blickfeld der Frage.
quelle
Hier ist die Lösung:
Um es gründlich zu testen, habe ich in die Zeichenfolge automatisch schließende Tags eingegeben:
Ich habe auch Tags eingegeben mit:
Sollten Sie im obigen Proof of Concept etwas finden, das nicht funktioniert, kann ich den Code analysieren, um meine Fähigkeiten zu verbessern.
<EDIT> Ich habe vergessen, dass die Frage des Benutzers darin bestand, das Parsen von selbstschließenden Tags zu vermeiden. In diesem Fall ist das Muster einfacher und wird folgendermaßen:
Der Benutzer @ridgerunner hat festgestellt, dass das Muster keine nicht zitierten Attribute oder Attribute ohne Wert zulässt . In diesem Fall bringt uns eine Feinabstimmung das folgende Muster:
</ EDIT>
Das Muster verstehen
Wenn jemand mehr über das Muster erfahren möchte, gebe ich eine Zeile an:
Kleiner Tipp: Um diesen Code besser analysieren zu können, muss der generierte Quellcode betrachtet werden, da ich keine HTML-Sonderzeichen angegeben habe.
quelle
<option selected>
. H. Stimmt auch nicht mit gültigen Tags mit nicht zitierten Attributwerten überein, d<p id=10>
. H.< a href="http://wtf.org" >
Ich bin mir ziemlich sicher, dass es legal ist, aber Sie stimmen nicht damit überein.Wann immer ich schnell etwas aus einem HTML-Dokument extrahieren muss, verwende ich Tidy, um es in XML zu konvertieren, und verwende dann XPath oder XSLT, um das zu bekommen, was ich brauche. In Ihrem Fall so etwas:
quelle
Ich habe zuvor ein Open-Source-Tool namens HTMLParser verwendet . Es wurde entwickelt, um HTML auf verschiedene Arten zu analysieren und erfüllt den Zweck recht gut. Es kann HTML als unterschiedlichen Treenode analysieren und Sie können seine API einfach verwenden, um Attribute aus dem Knoten abzurufen. Probieren Sie es aus und sehen Sie, ob dies Ihnen helfen kann.
quelle
Ich mag es, HTML mit regulären Ausdrücken zu analysieren. Ich versuche nicht, idiotisches HTML zu analysieren, das absichtlich kaputt ist. Dieser Code ist mein Hauptparser (Perl-Edition):
Es heißt htmlsplit und teilt den HTML-Code in Zeilen mit einem Tag oder Textblock in jeder Zeile auf. Die Zeilen können dann mit anderen Textwerkzeugen und Skripten wie grep , sed , Perl usw. weiter verarbeitet werden. Ich scherze nicht einmal :) Viel Spaß.
Es ist einfach genug, mein Perl-Skript "Slurp-Everything-First" in ein nettes Streaming-Ding umzuwandeln, wenn Sie riesige Webseiten verarbeiten möchten. Aber es ist nicht wirklich notwendig.
Ich wette, ich werde dafür herabgestimmt.
HTML Split
Entgegen meiner Erwartung erhielt dies einige positive Stimmen, daher werde ich einige bessere reguläre Ausdrücke vorschlagen:
Sie sind gut für XML / XHTML.
Mit geringfügigen Abweichungen kann es mit unordentlichem HTML umgehen ... oder zuerst HTML -> XHTML konvertieren.
Der beste Weg, reguläre Ausdrücke zu schreiben, ist der Lex / Yacc- Stil, nicht als undurchsichtige Einzeiler oder kommentierte mehrzeilige Monstrositäten. Das habe ich hier noch nicht gemacht; diese brauchen es kaum.
quelle
/(\w+)="(.*?)"/
setzt doppelte Anführungszeichen voraus. Es werden Werte in einfachen Anführungszeichen fehlen. In HTML-Version 4 und früheren Versionen ist ein nicht zitierter Wert zulässig, wenn es sich um ein einfaches Wort handelt./(\w+)="(.*?)"/
stimmt möglicherweise fälschlicherweise mit Text überein, der wie ein Attribut innerhalb eines Attributs aussieht, z<img title="Nope down='up' for aussies" src="..." />
. Wenn es global angewendet wird, stimmt es auch mit solchen Dingen in normalem Text oder in HTML-Kommentaren überein.Hier ist ein PHP-basierter Parser , der HTML mit einem gottlosen regulären Ausdruck analysiert. Als Autor dieses Projekts kann ich Ihnen sagen, dass es möglich ist, HTML mit Regex zu analysieren, aber nicht effizient. Wenn Sie eine serverseitige Lösung benötigen (wie ich es für mein wp-Typography WordPress-Plugin getan habe ), funktioniert dies.
quelle
Es gibt einige nette reguläre Ausdrücke zu ersetzen HTML mit BBCode hier . Beachten Sie für alle Neinsager, dass er nicht versucht, HTML vollständig zu analysieren, sondern nur zu bereinigen. Er kann es sich wahrscheinlich leisten, Tags abzutöten, die sein einfacher "Parser" nicht verstehen kann.
Zum Beispiel:
quelle
In Bezug auf die Frage der RegExp-Methoden zum Parsen von (x) HTML lautet die Antwort auf alle, die über einige Grenzen gesprochen haben: Sie sind nicht ausreichend geschult, um die Kraft dieser mächtigen Waffe zu beherrschen , da NIEMAND hier über Rekursion sprach .
Ein RegExp-agnostischer Kollege hat mich über diese Diskussion informiert, die sicherlich nicht die erste im Internet zu diesem alten und heißen Thema ist.
Nachdem ich einige Beiträge gelesen hatte, suchte ich als erstes nach dem "? R" -String in diesem Thread. Die zweite war die Suche nach "Rekursion".
Nein, heilige Kuh, keine Übereinstimmung gefunden.
Da niemand den Hauptmechanismus erwähnte, auf dem ein Parser aufgebaut ist, wurde mir schnell bewusst, dass niemand den Punkt verstand.
Wenn ein (x) HTML-Parser eine Rekursion benötigt, reicht ein RegExp-Parser ohne Rekursion für diesen Zweck nicht aus. Es ist ein einfaches Konstrukt.
Die schwarze Kunst von RegExp ist schwer zu beherrschen . Vielleicht gibt es weitere Möglichkeiten, die wir ausgelassen haben, als wir unsere persönliche Lösung ausprobiert und getestet haben, um das gesamte Web in einer Hand zu erfassen ... Nun, da bin ich mir sicher :)
Hier ist das magische Muster:
Probier es einfach.
Es ist als PHP-String geschrieben, daher bewirkt der Modifikator "s", dass Klassen Zeilenumbrüche enthalten.
Hier ist ein Beispiel für das PHP-Handbuch, das ich im Januar geschrieben habe: Referenz
(Achten Sie darauf, dass ich in diesem Hinweis den Modifikator "m" falsch verwendet habe. Er sollte gelöscht werden, obwohl er von der RegExp-Engine verworfen wird, da keine ^ oder $ Verankerung verwendet wurde.)
Nun könnten wir über die Grenzen dieser Methode aus einer informierten Sicht sprechen:
Trotzdem ist es nur ein RegExp-Muster, aber es offenbart die Möglichkeit, viele leistungsfähige Implementierungen zu entwickeln.
Ich habe dieses Muster geschrieben, um den rekursiven Abstiegsparser einer in meinem Framework erstellten Template-Engine zu betreiben. Die Leistung ist sowohl in Bezug auf die Ausführungszeiten als auch in Bezug auf die Speichernutzung wirklich großartig (nichts mit anderen Template-Engines zu tun, die dieselbe Syntax verwenden).
quelle
Wie viele Leute bereits betont haben, ist HTML keine reguläre Sprache, was das Parsen sehr schwierig machen kann. Meine Lösung besteht darin, es mit einem aufgeräumten Programm in eine normale Sprache umzuwandeln und dann einen XML-Parser zu verwenden, um die Ergebnisse zu nutzen. Dafür gibt es viele gute Möglichkeiten. Mein Programm wird mit Java mit der jtidy- Bibliothek geschrieben, um den HTML-Code in XML umzuwandeln, und dann mit Jaxen in xpath in das Ergebnis.
quelle
Die Teile erklärt:
<
: Startcharakter\s*
: Es kann Leerzeichen vor dem Tag-Namen haben (hässlich, aber möglich).(\w+)
: Tags können Buchstaben und Zahlen enthalten (h1). Nun,\w
passt auch zu '_', aber es tut nicht weh, denke ich. Wenn Sie neugierig sind, verwenden Sie stattdessen ([a-zA-Z0-9] +).[^/>]*
: alles außer>
und/
bis zum Schließen>
>
: schließen>
NICHT VERWANDT
Und für Leute, die reguläre Ausdrücke unterschätzen und sagen, dass sie nur so mächtig sind wie reguläre Sprachen:
a n ba n ba n, das nicht regelmäßig und nicht einmal kontextfrei ist, kann mit abgeglichen werden
^(a+)b\1b\1$
Rückreferenz FTW !
quelle
O(MN)
(M ist die Länge der regulären Ausdrücke, N ist die Textlänge). Rückreferenzen sind eine der Ursachen dafür. Die Implementierung in awk hat keine Rückreferenzen und stimmt mit derO(MN)
Zeit überein .Wenn Sie nur versuchen, diese Tags zu finden (ohne die Ambitionen zu analysieren), versuchen Sie diesen regulären Ausdruck:
Ich habe es in 30 Sekunden geschrieben und hier getestet: http://gskinner.com/RegExr/
Es entspricht den von Ihnen erwähnten Tags, während die von Ihnen angegebenen Typen ignoriert werden.
quelle
\/>
statt\\>
.\>
das habe ich gemeint. Ich wollte nie den regulären Ausdruck meines ursprünglichen Beitrags bearbeiten.\/
, dass Sie es gemeint haben , da dies genau das Gegenteil der Anforderungen bewirken würde. Vielleicht dachte ich, Sie bieten ein negatives Filtermuster an.Mir scheint, Sie versuchen, Tags ohne ein "/" am Ende abzugleichen. Versuche dies:
quelle
Es ist richtig, dass es beim Programmieren normalerweise am besten ist, dedizierte Parser und APIs anstelle von regulären Ausdrücken zu verwenden, wenn Sie mit HTML arbeiten, insbesondere wenn die Genauigkeit von größter Bedeutung ist (z. B. wenn Ihre Verarbeitung Sicherheitsauswirkungen haben könnte). Ich schreibe jedoch keiner dogmatischen Ansicht zu, dass XML-artiges Markup niemals mit regulären Ausdrücken verarbeitet werden sollte. Es gibt Fälle, in denen reguläre Ausdrücke ein großartiges Werkzeug für den Job sind, z. B. beim einmaligen Bearbeiten in einem Texteditor, beim Beheben fehlerhafter XML-Dateien oder beim Umgang mit Dateiformaten, die aussehen, aber nicht ganz XML sind. Es gibt einige Probleme, die Sie beachten müssen, aber sie sind nicht unüberwindbar oder sogar unbedingt relevant.
Ein einfacher Regex wie
<([^>"']|"[^"]*"|'[^']*')*>
ist normalerweise gut genug, in Fällen wie den gerade erwähnten. Alles>
in allem ist es eine naive Lösung, aber es erlaubt korrekt nicht codierte Symbole in Attributwerten. Wenn Sie beispielsweise nach einemtable
Tag suchen , können Sie es als anpassen</?table\b([^>"']|"[^"]*"|'[^']*')*>
.Um einen Eindruck davon zu bekommen, wie ein "fortgeschrittener" HTML-Regex aussehen würde, können Sie im Folgenden das Verhalten des realen Browsers und den HTML5-Parsing-Algorithmus nachvollziehen:
Das Folgende entspricht einer ziemlich strengen Definition von XML-Tags (obwohl nicht der gesamte Satz von Unicode-Zeichen berücksichtigt wird, die in XML-Namen zulässig sind):
Zugegeben, diese berücksichtigen nicht den umgebenden Kontext und einige Randfälle, aber selbst solche Dinge könnten behandelt werden, wenn Sie es wirklich wollten (z. B. indem Sie zwischen den Übereinstimmungen eines anderen regulären Ausdrucks suchen).
Verwenden Sie am Ende des Tages das für den Job am besten geeignete Werkzeug, auch wenn es sich bei diesem Werkzeug zufällig um einen regulären Ausdruck handelt.
quelle
Obwohl es nicht geeignet und effektiv ist, reguläre Ausdrücke für diesen Zweck zu verwenden, bieten reguläre Ausdrücke manchmal schnelle Lösungen für einfache Übereinstimmungsprobleme, und meiner Ansicht nach ist es nicht so schrecklich, reguläre Ausdrücke für triviale Arbeiten zu verwenden.
Es gibt einen endgültigen Blog-Beitrag über übereinstimmende innerste HTML-Elemente, die von Steven Levithan geschrieben wurden.
quelle