Schrift
[thread]5696[/thread]

Links filtern: reguläre ausdrücke

Leser: 1


<< |< 1 2 >| >> 19 Einträge, 2 Seiten
Gast Gast
 2003-09-07 16:34
#85071 #85071
Hi ihr Perler,
ich habe ein Problem:

ich versuche gerade eine eigene regex zu schreiben, die links filtern soll, seht sie euch mal an:
Code: (dl )
1
2
3
4
if($dat =~ /<a+[\s]+href+=+([\w])+>/i)
{
print "FOUND";
}


sie soll hinterher den ganzen link ausgeben..aber ich kriegs irgendwie nicht hin..könnt ihr mir helfen?

Paule
pq
 2003-09-07 16:48
#85072 #85072
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
Code: (dl )
1
2
3
4
5
6
7
8
9
10
if($dat =~ /<a+[\s]+href+=+([\w])+>/i)
              |    |    | |      |
    mehrere "a"    |    | |      |
 mehrere whitespaces    | |      |
              mehrere "f" |      |
                mehrere "="      |
                        mehrere \w

dieser string würde also matchen:
"<aaa   hreffff====abcde>"

vielleicht solltest du erst nochmal perlintro
lesen. ausserdem sollte man html gar nicht mit regexes parsen,
sondern sich lieber auf module verlassen, die das viel
besser können, HTML::Parser, HTML::Treebuilder, etc...
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
[E|B]
 2003-09-07 17:01
#85073 #85073
User since
2003-08-08
2561 Artikel
HausmeisterIn
[Homepage] [default_avatar]
Hi!

Code: (dl )
1
2
3
if($code =~ !<a href=".+">.+</a>!gi){
print "Anchor was found!";
}
Gruß, Erik!

s))91\&\/\^z->sub{}\(\@new\)=>69\&\/\^z->sub{}\(\@new\)=>124\&\/\^z->sub{}\(\@new\)=>);
$_.=qq~66\&\/\^z->sub{}\(\@new\)=>93~;for(@_=split(/\&\/\^z->sub{}\(\@new\)=>/)){print chr;}

It's not a bug, it's a feature! - [CGI-World.de]
pq
 2003-09-07 17:09
#85074 #85074
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
[E|B
,07.09.2003, 15:01]
Code: (dl )
1
2
3
if($code =~ !<a href=".+">.+</a>!gi){
    print "Anchor was found!";
}

schöner versuch, leider falsch, aus den gründen, die ich oben schon
genannt habe. was macht deine regex aus dem hier:
<a
href="....">Link</a>

oder aus
<a href="...">Link1</a><a href="...">Link2</a>
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
Dubu
 2003-09-07 17:09
#85075 #85075
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Zerlegen wir die Regex doch mal:
Code: (dl )
1
2
3
4
5
6
7
8
9
<           # Eine spitze Klammer auf
a+          # Eine Folge von einem oder mehr 'a's
[\s]+       # Eine Folge von einem oder mehr Zeichen aus der Menge [\s], d.h. Whitespace
href+       # Die Buchstabenfolge 'hre', gefolgt von einem oder mehr 'f's
=+          # Eine Folge von einem oder mehr Gleichheitszeichen
([\w])+     # Eine Folge von einem oder mehr Zeichen aus der Menge [\w], also Wortzeichen
            # Das sind A-Z, a-z und '_'.
            # Jedes einzelne Zeichen wird in einem der Speicher $1, $2, etc. gemerkt
>           # Eine spitze Klammer zu

Du bist dir ueber die Bedeutung des '+' in regulaeren Ausdruecken wahrscheinlich nicht ganz im Klaren. Hast du perlrequick gelesen?

Da HTML deutlich komplizierter ist, als deine Regex oben, solltest du fuer diese Aufgabe einen HTML-Parser nehmen, in diesem Fall am einfachsten CPAN:HTML::LinkExtor.
Ausnahme: Du kennst genau den Aufbau der <a href>-Tags und kannst deshalb mit einer eingeschraenkten Regex leben.

Ein Beispiel:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if ($date =~ /
    <a          # spitze Klammer auf und 'a'
    \s+         # Eine Folge von einem oder mehr Whitespacezeichen
    href        # Der Text 'href'
    \s*         # Eine Folge von keinem oder mehr Whitespacezeichen
    =           # Ein Gleichheitszeichen
    \s*         # Eine Folge von keinem oder mehr Whitespacezeichen
    "           # Ein Anfuehrungszeichen
    ([^"]+)     # Eine Folge von einem oder mehr Zeichen, die kein Anfuehrungszeichen sind.
                # Die Folge wird sich in $1 gemerkt.
    "           # Ein Anfuehrungszeichen
    \s*         # Eine Folge von keinem oder mehr Whitespacezeichen
    >           # Eine spitze Klammer zu
    /xi                # Ende der Regex; Kommentare erlauben und ignore-case einschalten
    )
[...]

Diese Regex erkennt schon einige <a href>-Tags, aber
- das href muss der erste Parameter sein (kein <a style=... href=...>! )
- die URI muss in Anfuehrungszeichen stehen (was der HTML-Spec entspricht)
- die Anfuehrungszeichen muessen doppelt sein (was nicht der HTML-Spec entspricht)
- nach der URI duerfen keine weiteren Parameter stehen (kein <a href=... style=...>! )

Du siehst, da sind ziemlich viele Einschraenkungen, wenn man es mit einer simplen Regex parsen will. Nimm lieber das Modul.
Ishka
 2003-09-07 20:23
#85076 #85076
User since
2003-08-04
771 Artikel
HausmeisterIn
[Homepage] [default_avatar]
Ok, einmal als RegEx, aber nimm wirklich lieber Module
Code (perl): (dl )
1
2
3
4
5
6
7
my $link='';
if($dat =~ /<a\s+href=("[^"]+"|[^ >]+)(?:\s+[a-z]+=(?:"[^"]+"|[^ >]+))*>/i)
{
$link=$1;
$link=$1 if $link=~m#^"(.*)"$#;
print "Link $link gefunden";
}

Zumindestens falls ich keine Fehler eingebaut hab\n\n

<!--EDIT|Ishka|1062951972-->
sub z{if(@_){1while$x[$k=rand 10];t($t=$x[$k]=1)}print map"$z[$x[$_]]$_".($_%3?
"":"\n"),1..9}sub t{$j=0;$x[$_+1]==$t&&($j+=2**$_)for 0..8;z,die"Gewinner $z[$t]
"if grep$_==($j&$_),7,56,73,84,146,273,292,448;z,die"Gleichstand\n"if@x>9&&!grep
!$_,@x}@x=4;@z=qw{. [ (};z$^T&1;while(<>){next if$_>9||$x[$_];t$t=$x[$_]=2;z 1}
steinwolf
 2003-09-07 21:41
#85077 #85077
User since
2003-08-04
367 Artikel
BenutzerIn
[default_avatar]
funktioniert aber wirklich nur wenn der link auch direkt mit href eingeleitet wird und nicht mit target und konsorten :)
"Did you know? You can use your old motor oil to fertilize your lawn." - Blinkster - Professionelles EDV Forum
Ishka
 2003-09-07 21:44
#85078 #85078
User since
2003-08-04
771 Artikel
HausmeisterIn
[Homepage] [default_avatar]
Ups, stimmt. Ich weiß doch, warum ich sagte, lieber mit Modul. Nagut, dann halt
Code (perl): (dl )
if($dat =~ /<a(?:\s+[a-z]+=(?:"[^"]+"|[^ >]+))*\s+href=("[^"]+"|[^ >]+)(?:\s+[a-z]+=(?:"[^"]+"|[^ >]+))*>/i)
sub z{if(@_){1while$x[$k=rand 10];t($t=$x[$k]=1)}print map"$z[$x[$_]]$_".($_%3?
"":"\n"),1..9}sub t{$j=0;$x[$_+1]==$t&&($j+=2**$_)for 0..8;z,die"Gewinner $z[$t]
"if grep$_==($j&$_),7,56,73,84,146,273,292,448;z,die"Gleichstand\n"if@x>9&&!grep
!$_,@x}@x=4;@z=qw{. [ (};z$^T&1;while(<>){next if$_>9||$x[$_];t$t=$x[$_]=2;z 1}
steinwolf
 2003-09-07 21:54
#85079 #85079
User since
2003-08-04
367 Artikel
BenutzerIn
[default_avatar]
mein armer editor..
der kommt mit dem highlighting überhaupt nicht mehr klar :D
"Did you know? You can use your old motor oil to fertilize your lawn." - Blinkster - Professionelles EDV Forum
Dubu
 2003-09-08 01:29
#85080 #85080
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
@Ishka: Und jetzt bitte noch einbauen, dass die URL auch in einfachen Anfuehrungszeichen stehen kann... ;-)
<< |< 1 2 >| >> 19 Einträge, 2 Seiten



View all threads created 2003-09-07 16:34.