Thread Suche und Ersetzen von <?php und <!-- (15 answers)
Opened by newperler at 2011-04-26 19:20

clms
 2011-04-28 14:48
#148054 #148054
User since
2010-08-29
373 Artikel
BenutzerIn
[default_avatar]
2011-04-28T06:39:20 newperler
Wie man einen HTML-Parser in ein vorhandens Script einbindet, weiß ich nicht, der Author des Scripts hat das Entfernen auch mit anderen Tags auf dem oben beschriebenen Weg erreicht, siehe z.B. <!--nosearch--><!--/nosearch-->. Vielleicht ergibt sich daraus ja ein Tipp?

<?php irgendwas ?>, die gefundenen Tags sollen komplett aus $contents gelöscht werden.
<!-- irgendwas -->, die gefundenen Tags sollen komplett aus $contents gelöscht werden.

In >99% der Fälle kannst Du mit relativ einfachen Regex Deine Aufgabe erledigen, weil zwischen dem Start von <?php und dem abschließenden ?> nichts kommt, was Deine Regex aus dem Tritt bringen würde.
Wenn Du Kontrolle über die Files hast, die Du einliest (oder zumindest die Skripte/Programme die sie erzeugen) kannst Du die Quote wahrscheinlich sogar auf >99.99% hochtreiben. Aber mit einfachen Regex wirst Du nie alle Ausnahmefälle abdecken können. Irgendwann kracht es dann, weil Dein Skript nicht mit gültigem HTML zurechtkommt.

Für die HTML-Kommentare gilt im Prinzip das gleiche, wobei hier das Fehlerpotenzial tendenziell höher ist, weil Kommentare eben nicht durch <!-- am Anfang und --> am Ende definiert sind sondern innerhalb eines <! ... >[c] durch [c]-- ein- und wieder ausgeschaltet werden.

Wenn Du auf der sicheren Seite sein willst, verwende CPAN:HTML::Parser. Der kommt mit den Sonderfällen zurecht.

Mit CPAN:HTML::TreeBuider ist das sehr einfach
(ungetestetes Code-Fragment):
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
use HTML::TreeBuilder;

# TreeBulder-Objekt anlegen
my $tree = HTML::TreeBuilder-new();

# HTML-File einlesen
$tree->parse_file($filename);

# HTML aus String einlesen
$tree->parse($htmlinput);
# weitere Zeilen:  $tree->parse($htmlinput2);
$tree->eof();   # eingabe beendet

# Ausgabe
my $output = $tree->as_HTML();

Je nachdem, ob Du das HTML direkt aus dem File oder aus einem String einlesen willst, musst Du Zeile 7 bzw. 10-12 auskommentieren.

Und das Beste für Dich: die php-Tags und HTML-Kommentare entfernt
CPAN:HTML::TreeBuilder schon in der Defaulteinstellung.
(Und kleinere Probleme in der HTML-Syntax werden ebenfalls gefixt.)

Falls Du kein komplettes HTML-Dokument einliest, sondern nur Ausschnitte (und auch nur diese Ausschnitte zurückhaben willst), wird die Ausgabe etwas komplizierter (ebenfalls ungetestet):
Code (perl): (dl )
my @htmlparts = map {$_->as_HTML()} $tree->guts();

Zur Erklärung: $tree-guts() liefert eine Liste mit allen Teilen des HTML-Trees, die du via parse eingegeben hast. Umgebende <html> Tags, die der TreeBuilder selbst hinzufügt, um einen gültigen HTML-Tree zu bekommen, werden dabei weggelassen. map {$_->as_HTML()} verwandelt die Teilbäume dann wieder in HTML.

ACHTUNG:
Ich habe gerade einen kurzen Blick in das Skript geworfen und dabei
noch einige sehr unsichere Regex gefunden.

So wird z.B. nach <meta name="description" content="..."> gesucht.
Das funktioniert auch (solange die Quotes um description balanced sind und in content kein unescaped " oder ' steht).
Aber wenn stattdessen im HTML <meta content="..." name="description"> steht
- was von der Bedeutung völlig equivalent ist - wird es nicht mehr gefunden.

Wenn Du Dein HTML durch den TreeBuilder jagst, ist nicht mehr garantiert, dass die Reihenfolge der Attribute in der Ausgabe unverändert ist. Die obige Regex würde nur noch mit einer 50%-Chance zuschlagen.
(Das gleiche Problem tritt auf, wenn die Reihenfolge in der Source getauscht wird.)

Saubere Programmierung wäre, dass HTML-Dokument in den CPAN:HTML::TreeBuilder zuladen,
dann den Tree nach einem Element tag='meta' mit dem Attribute
name=description
zu durchsuchen und in in diesem Element das Attribut 'content' auszuwerten.
Das geht recht einfach und ist sehr robust, weil Du Dich um Quotes,
die Reihenfolge der Attribute u.ä. nicht kümmern musst
- das machen Parser/TreeBuilder für Dich und CPAN:HTML::TreeBuilder
hat sehr leistungsfähige und komfortable Methoden zum Durchsuchen des HTML-Trees.
Allerdings ist es natürlich trotzdem Arbeit das ganze Skript umzustellen.

View full thread Suche und Ersetzen von <?php und <!--