Eine Zeichenfolge wie folgt gegeben:
%Vor%... und ein Suchstring wie "foo", ich möchte alle Vorkommen von "foo" im HTML-Text hervorheben - aber nicht innerhalb eines Tags. Mit anderen Worten, ich möchte das bekommen:
%Vor%Ein einfaches Suchen und Ersetzen funktioniert jedoch nicht, da es einen Teil der URL im & lt; a & gt; tag href.
Um das Obige in Form einer Frage auszudrücken: Wie schränke ich eine Regex so ein, dass sie nur Text außerhalb von HTML-Tags abgleicht?
Hinweis: Ich verspreche, dass der fragliche HTML-Code niemals pathologisch sein wird wie:
%Vor%Bearbeiten: Ja, mir ist natürlich klar, dass es in CPAN komplexe Bibliotheken gibt, die selbst den abscheulichsten HTML-Code parsen können und somit die Notwendigkeit für einen solchen Regex verringern. Bei vielen Gelegenheiten würde ich das verwenden. Dies ist jedoch nicht eine dieser Gelegenheiten, da es wichtig ist, dieses Skript kurz und einfach ohne externe Abhängigkeiten zu halten. Ich möchte nur einen einzeiligen Regex.
Edit 2: Auch hier weiß ich, dass Template :: Refine :: Fragment all meinen HTML-Code für mich analysieren kann. Wenn ich eine Anwendung schreiben würde, würde ich sicherlich eine solche Lösung verwenden. Aber das ist keine Anwendung. Es ist kaum mehr als ein Shell-Skript. Es ist ein Stück Weg Code. Eine einzelne, eigenständige Datei zu sein, die weitergegeben werden kann, ist in diesem Fall von großem Wert. "Hey, führe dieses Programm aus" ist eine viel einfachere Anweisung als "Hey, installiere ein Perl-Modul und führe dieses dann aus - warte, was, du hast CPAN vorher noch nie benutzt? Okay, laufe Perl -MCPAN -e Shell (vorzugsweise als Root) und dann wird es dir eine Menge Fragen stellen, aber du musst sie nicht wirklich beantworten. "Nein, hab keine Angst, das wird nichts kaputt machen. Schau, du brauchst es nicht um jede Frage sorgfältig zu beantworten - drücken Sie einfach immer wieder Enter. Nein, ich verspreche, es wird nichts kaputt machen. "
Multiplizieren Sie nun das oben Genannte mit einer großen Anzahl von Benutzern, die sich fragen, warum das einfache Skript, das sie benutzt haben, nicht mehr so einfach ist, wenn nur der Suchbegriff fett gedruckt wird.
Während also Template :: Refine :: Fragment die Antwort auf die HTML-Analysefrage einer anderen Person sein kann, ist es nicht die Antwort auf diese Frage. Ich möchte nur einen regulären Ausdruck, der mit der sehr begrenzten Teilmenge von HTML arbeitet, die das Skript tatsächlich analysieren soll.
Im Allgemeinen möchten Sie den HTML-Code in ein DOM zerlegen und dann die Textknoten durchlaufen. Ich würde Template :: Refine dafür verwenden:
%Vor%Dies gibt aus:
%Vor%Analysieren Sie strukturierte Daten nicht mit regulären Ausdrücken. HTML ist nicht "normal", es ist "kontextfrei".
Bearbeiten: Schließlich, wenn Sie den HTML-Code in Ihrem Programm generieren, und Sie müssen solche Transformationen auf Strings tun, "UR DOIN IT WRONG". Sie sollten ein DOM erstellen und es nur dann serialisieren, wenn alles transformiert wurde. (Sie können TR jedoch weiterhin über den new_from_dom
-Konstruktor verwenden.)
Um den Inhalt variabler Größe von sogar verschachtelten Tags zu entfernen, können Sie diese Regex verwenden, die in der Tat eine Mini-reguläre Grammatik dafür ist. (Hinweis: PCRE-Maschine)
(? & lt; = & gt;) ((?: \ w +) (?: \ s *)) (? 1) *