Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]893[/thread]

Match-Problem...

Leser: 1


<< |< 1 2 >| >> 13 Einträge, 2 Seiten
olruebe01
 2007-02-20 18:26
#9640 #9640
User since
2006-01-19
192 Artikel
BenutzerIn
[default_avatar]
Hallo,

nach meiner gestriegen Frage arbeite ich mich gerade durchs pattermatching und bekomme folgendes einfach nicht hin:

Ich möchte aus einem Text, der den HTML-Code für eine Tabelle enthällt, Zeilen löschen (<TR>), die nur eine Zelle (<TD>) mit beliebigem Inhalt enthalten. Sofern in einer Zeile 2 TDs vorkommen, soll die Zeile bestehen bleiben.

Mein Ansatz:
 
Code: (dl )
1
2
while ($HTML=~ /<tr><td VALIGN=TOP>([^<td>].*)<\/td><\/tr>/) {
$HTML =~ s/<tr><td VALIGN=TOP>[^<td>].*<\/td><\/tr>//;}


Mein Gedanke ist dabei: Suche alles zwischen
<tr><tr><td VALIGN=TOP>...
[ausser einem weiteren <td>]
und ...</td></tr>
und lösche das, wenn zutrefend.

Ich bekomme es nicht hin. Ich habe schon diverse Varianten versucht aber so, wie ich mir das denke, bekomme ich es nicht auf die Reihe...

In der bestehenden EINEN Zelle, die gelöscht werden soll, befindet sich auch HTML, wie z.B. <Font...> und <B>

Die Klammern habe ich nur gesetzt, um mir zur Kontrolle anzeigen zu lassen, was gefunden wurde...

Ich Danke Euch schonmal wieder!!
renee
 2007-02-20 19:17
#9641 #9641
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Warum verwendest Du keine Module wie CPAN:HTML::TableExtract?
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
olruebe01
 2007-02-20 20:21
#9642 #9642
User since
2006-01-19
192 Artikel
BenutzerIn
[default_avatar]
Wäre vielleicht ne Möglichkeit. Dennoch würde ich die Problematik gerne verstehen. Was mache ich bei meinem Gedanken falsch? Vielleicht geht es beim nächsten Mal nicht um eine Tabelle...
murphy
 2007-02-21 13:35
#9643 #9643
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
[quote=olruebe01,20.02.2007, 16:26]Mein Ansatz:
Code: (dl )
1
2
while ($HTML=~ /<tr><td VALIGN=TOP>([^<td>].*)<\/td><\/tr>/) {
$HTML =~ s/<tr><td VALIGN=TOP>[^<td>].*<\/td><\/tr>//;}
[/quote]

* Statt der while-Schleife wäre es vielleicht sinnvoll, dem s///-Operator das g-Flag zu verpassen.

* [^<td>].* matcht auf jedes beliebige Zeichen außer '<', '>', 't' oder 'd', gefolgt von beliebig vielen beliebigen Zeichen -- das ist, glaube ich, nicht das was Du wolltest. Ich denke, Du suchst eher ein Konstrukt wie .*(?!<td>).

* Wenn Deine Lösung halbwegs zuverlässig mit unterschiedlichem HTML-Code klarkommen soll, würde ich bei diesem Problem dringend empfehlen, einen HTML-Parser zu verwenden und von einfachen regulären Ausdrücken abzusehen.
When C++ is your hammer, every problem looks like your thumb.
olruebe01
 2007-02-21 17:00
#9644 #9644
User since
2006-01-19
192 Artikel
BenutzerIn
[default_avatar]
Hi murphy,
wie gesagt: Das soll jetzt mal Beispielhaft sein.

Deine Idee habe ich jetzt so umgesetzt:
Code: (dl )
@vorkommen = ( $HTML =~ m/<tr><td>.*(?!<td )<\/td><\/tr>/g );  


Tut aber nicht, was es soll. Es werden immernoch Passagen gefunden, die <td> enthalten.

Vielleicht ein anderes Beispiel:
Das ganze soll mir aus einem mehrzeiligen Text ALLE Textpassagen finden, die mit "Haus" beginnen, mit "Strasse" enden und wo zwischen Haus und Strasse NICHT "Baum" vorkommt.
Diese Textpassage kann im Text ein Mal, mehrmals oder gar nicht vorkommen.


Die Whileschleife verwende ich im Moment, um mir das Ergebnsi der Suche etwas übersichtlicher Anzeigen zu lassen.
murphy
 2007-02-22 20:19
#9645 #9645
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Probier mal (?:.(?!<td))*. Das könnte gehen, wenn die RegEx-Maschine dabei nicht bereits aussteigt.
When C++ is your hammer, every problem looks like your thumb.
olruebe01
 2007-02-22 21:13
#9646 #9646
User since
2006-01-19
192 Artikel
BenutzerIn
[default_avatar]
Hi murphy,

das hört sich ja so an, als ob es keinen "Befehl" gibt für NICHT "diesunddas"... Für einzelne Zeichen ist wohl unproblematisch aber für eine Zeichenkette gibt es das nicht???
murphy
 2007-02-22 21:43
#9647 #9647
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Stimmt genau, es gibt bei regulären Ausdrücken keine Notation für "matche alles außer einem bestimmten String". Es gibt nur den negativen Lookahead mit (?!...).

Ich denke, das Fehlen eines solchen Befehles hat einfach den Grund, dass nicht klar ist, wieviele Zeichen von "alles außer einem bestimmten String" gematcht werden sollten.
When C++ is your hammer, every problem looks like your thumb.
olruebe01
 2007-02-23 15:24
#9648 #9648
User since
2006-01-19
192 Artikel
BenutzerIn
[default_avatar]
Ne ne... ich würde das ja schon mit andere Bedingungen kombinieren wollen.
Etwas wie

/(Anfang.*(NOT"Baum")Ende)/

so dass sich (NOT"Baum") auf die vorherige .* bezieht. Damit wäre der Anfangs- und Endpunkt des zu matchenden Strings gegeben.

Wie wäre denn dann sowas: /(Anfang.*(?!Baum)Ende)/\n\n

<!--EDIT|olruebe01|1172237149-->
topeg
 2007-02-23 22:30
#9649 #9649
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
allso du willst alles finden was zwischen
Code: (dl )
<tr><td VALIGN=TOP>
und
Code: (dl )
<\td><\tr>
steht sammt den Tags selber löschen. Dabei soll im Inhalt dazwischen kein "</td><td>" auftauchen.

Ich würde das so machen. :
Code: (dl )
$HTML =~ s|(<tr><td VALIGN=TOP>.*?</td></tr>[\s\r\n]*)|($_=$1)=~m\</td>.*?<td>\s?$_:""|egs;

(EDIT: bei [perl]-Tags wird aus "$1" "ü" ???)
Zu den Schaltern:
"s" sagt der gesammte String soll als "single line" gehandhabt werden (\r\n können direckt gesucht werden).
Bei "g" wird glogal gematched, was heißt es werden alle Strings gesucht, die auf das RegExp passen.
Mit "e" wird der Ersetzungsstring als Perlcode ausgeführt.
Und hier ist auch der Trick. Ich führe im Ersetungsstring selber eine RegExp aus, in der ich frage ob im gefunden String
Code: (dl )
</td>.*?<td>
vorkommt wenn ja, dann soll der String unverändert wieder eingesetzt werden, wenn sie nicht trifft, dann soll der String durch einen leeren ersetzt werden.\n\n

<!--EDIT|topeg|1172262807-->
<< |< 1 2 >| >> 13 Einträge, 2 Seiten



View all threads created 2007-02-20 18:26.