Schrift
[thread]6388[/thread]

Perl regex Fehler



<< |< 1 2 >| >> 20 Einträge, 2 Seiten
dax42
 2004-07-09 12:20
#84076 #84076
User since
2004-06-16
24 Artikel
BenutzerIn
[default_avatar]
Hallo,

ich habe folgende regex geschrieben:

Code: (dl )
my ($data) = $c =~ /(">(T[0-9]+)<\/A>,|.|\n)*/;


Damit soll eine website gematcht werden, daher </A>..
Das, was als Beschreibung der website steht, nämlich T[0-9]+, will ich ausgegeben haben, darum steht das nochmal in Klammern.

Wenn ich das ganze ausführe, gibt er mir, wenn er an diese Stelle kommt, folgenden Fehler:
Code: (dl )
Segmentation fault


Warum?
Danke!
Crian
 2004-07-09 12:33
#84077 #84077
User since
2003-08-04
5866 Artikel
ModeratorIn
[Homepage]
user image
Zeig bitte mal etwas mehr Code. Segmentation Fault klingt nach einem ganz anderen Problem.

Frage: Könnte es auch mal vorkommen, dass auf Deiner Webseite Links mit </a> enden?

Es gibt nette Module um HTML zu Parsen, die nehmen Dir eine Menge Arbeit ab. Etwa HTML::Parser\n\n

<!--EDIT|Crian|1089362337-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
esskar
 2004-07-09 12:36
#84078 #84078
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
1. Welches OS, welche Perl-Version
2. Hast du Beispiel Daten?
3. G****r Fehler; Segmentation fault sind bei Scriptsprachen recht selten
pq
 2004-07-09 12:39
#84079 #84079
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
poste mal ein minimales beispiel von $c, womit der fehler
auftritt. weiterhin dein betriebssystem und die perl-version.
ausserdem frage ich mich, ob du weisst, was diese regex
matched. mehrere punkte hintereinander z.b.
ausgegeben bekommt du aber nicht das T..., sondern
du hast ja klammern um fast den gesamten ausdruck,
also wirst du den auch bekommen.
um die äußeren klammern zu entwerten, schreibst du
(?=...) anstatt (...)
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
dax42
 2004-07-09 12:44
#84080 #84080
User since
2004-06-16
24 Artikel
BenutzerIn
[default_avatar]
Hm, mehr code...
Das würde ich gern vermeiden, ist nämlich ziemlich viel und nicht so spannend. Aber wenn ich die Regex auskommentiere, erhalte ich keinen Fehler und wenn ich die | wegnehme, also den regex ein wenig umschreibe, dann erhalte ich auch keinen Fehler (aber auch nicht die richtigen matches). Bevor ich den match aufrufe, hole ich mir in $c nur den html-code der zu parsenden seite, was ich auch schon des öfteren vorher gemacht habe, darin kann der Fehler also nicht liegen.

Code: (dl )
1
2
my @data = $c =~ /">BS<\/A>\s*\-?[0-9]+.*">(R[0-9]+)<\/A>(">(T[0-9]+)<\/A>,|.|\n)*">(T[0-9]+)\<\/A>./g;
print "@data\n";


Das ist der komplette Regex. Die Website sieht so aus (Ausschnitt):
Code: (dl )
1
2
3
4
5
XX
<A HREF="/pub/databases/transfac/doc/gene1.html#BS" target="_new">BS</A> -202 -135 <A HREF="/cgi-bin/pub/databases/transfac/getTF.cgi?AC=R00929">R00929</A>; HS$IFNB_14.
<A HREF="/pub/databases/transfac/doc/gene1.html#BS" target="_new">BS</A> -167 -94 <A HREF="/cgi-bin/pub/databases/transfac/getTF.cgi?AC=R00916">R00916</A>; HS$IFNB_01; Binding factors: R2 <A HREF="/cgi-bin/pub/databases/transfac/getTF.cgi?AC=T00712">T00712</A>.
<A HREF="/pub/databases/transfac/doc/gene1.html#BS" target="_new">BS</A> -100 -61 <A HREF="/cgi-bin/pub/databases/transfac/getTF.cgi?AC=R00917">R00917</A>; HS$IFNB_02; Binding factors: IRF1 <A HREF="/cgi-bin/pub/databases/transfac/getTF.cgi?AC=T00422">T00422</A>, IRF-2
<A HREF="/pub/databases/transfac/doc/gene1.html#BS" target="_new">BS</A> <A HREF="/cgi-bin/pub/databases/transfac/getTF.cgi?AC=T00425">T00425</A>.


Any idea?
Wonach klingt denn segmentation fault?
dax42
 2004-07-09 12:52
#84081 #84081
User since
2004-06-16
24 Artikel
BenutzerIn
[default_avatar]
Also vielleicht habe ich das mit dem Gruppieren falsch verstanden, das kann natürlich sein.

Ich wollte folgendes sagen: matche ">T[0-9]+<\/A>, oder .(also irgendeinen character) oder newline.
Im ersten Fall will ich T[0-9]+ haben. Diese ganze oder-Sache soll mehrmals gematcht werden, daher habe ich es komplett in Klammern gesetzt und hinten ran noch einen Stern.

Geht das so oder nicht? Wenn nicht, wie dann?
OS: Mac OS 10.3.4 (Panther)
Perl: wie bekomme ich das raus? Ist bei Mac OSX auf jeden Fall schon eingebaut, weil Unix.
dax42
 2004-07-09 12:55
#84082 #84082
User since
2004-06-16
24 Artikel
BenutzerIn
[default_avatar]
Code: (dl )
1
2
3
4
>perl -v

This is perl, v5.8.1-RC3 built for darwin-thread-multi-2level
(with 1 registered patch, see perl -V for more detail)


Danke schonmal für die Hilfe!
renee
 2004-07-09 13:13
#84083 #84083
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Code: (dl )
1
2
3
4
5
6
7
8
9
10
#! /usr/bin/perl

my $string = qq~<A HREF="/pub/databases/transfac/doc/gene1.html#BS" target="_new">BS</A> -202 -135 <A HREF="/cgi-bin/pub/databases/transfac/getTF.cgi?AC=R00929">R00929</A>; HS$IFNB_14.
<A HREF="/pub/databases/transfac/doc/gene1.html#BS" target="_new">BS</A> -167 -94 <A HREF="/cgi-bin/pub/databases/transfac/getTF.cgi?AC=R00916">R00916</A>; HS$IFNB_01; Binding factors: R2 <A HREF="/cgi-bin/pub/databases/transfac/getTF.cgi?AC=T00712">T00712</A>.
<A HREF="/pub/databases/transfac/doc/gene1.html#BS" target="_new">BS</A> -100 -61 <A HREF="/cgi-bin/pub/databases/transfac/getTF.cgi?AC=R00917">R00917</A>; HS$IFNB_02; Binding factors: IRF1 <A HREF="/cgi-bin/pub/databases/transfac/getTF.cgi?AC=T00422">T00422</A>, IRF-2
<A HREF="/pub/databases/transfac/doc/gene1.html#BS" target="_new">BS</A> <A HREF="/cgi-bin/pub/databases/transfac/getTF.cgi?AC=T00425">T00425</A>.>.~;

my @infos = $string =~ /<a[^>]+>([RT][0-9]+)<\/a>/ig;

print $_,"\n" for(@infos);
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/
dax42
 2004-07-09 13:14
#84084 #84084
User since
2004-06-16
24 Artikel
BenutzerIn
[default_avatar]
Also vielleicht noch was zur Klarstellung des Problems:
Die Website sieht so aus (jetzt mal ohne HTML-Code, das ist ja furchtbar):

X
BS     -202   -135   R00929; HS$IFNB_14.
BS     -167    -94   R00916; HS$IFNB_01; Binding factors: R2 T00712.
BS     -100    -61   R00917; HS$IFNB_02; Binding factors: IRF1 T00422, IRF-2
BS     T00425.
BS      -94    -78   R00918; HS$IFNB_03.
BS      -82    -60   R00919; HS$IFNB_04; Binding factors: IBP-1 T00400, ICSBP
BS      T00402, IRF1 T00422, IRF-2 T00425.
BS      -79    -64   R00924; HS$IFNB_09.
BS      -77    -64   R00925; HS$IFNB_10; Binding factors: ITF T00431.
BS      -74    -63   R00926; HS$IFNB_11; Binding factors: PRDI-BFc T01037.
BS      -74    -63   R00927; HS$IFNB_12; Binding factors: ICSBP T00402, IRF1
BS      T00423, PRDI-BF1 T00929.
BS      -69    -49   R00920; HS$IFNB_05; Binding factors: NF-kappaB1 T00593.

Wie gesagt, das ist nur ein Ausschnitt. Alle BS sowie die T[0-9]+ und die R[0-9]+ sind Links.

Zuerst habe ich mit folgendem regex gematcht, das hat auch funktioniert:
my @data = $c =~ /">BS<\/A>\s*\-?[0-9]+.*">(R[0-9]+)<\/A>.*">(T[0-9]+)<\/A>\./g
Damit erhielt ich alle Ts und Rs in Zeilen, in denen genau ein R.. steht und genau ein T..
Nun gibt es ja oben auch Zeilen, in denen mehrere T's stehen, zugehörig zu einem R. Die will ich auch alle haben, schön hintereinander im Array, damit ich sie dann anschließend auch noch zuordnen kann (sie müssen also in der richtigen Reihenfolge bleiben).

Das habe ich mit dem oben genannten versucht, aber Fehler.
?? Danke.\n\n

<!--EDIT|dax42|1089364619-->
Crian
 2004-07-09 13:15
#84085 #84085
User since
2003-08-04
5866 Artikel
ModeratorIn
[Homepage]
user image
Wenn Du es denn unbedingt ohne Modul haben willst:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
{
local $/; # slurpmode
my $html = <DATA>;
my @link = grep {$_ =~ /^[RT]\d+$/} $html =~ m~<a\s[^>]+>([^<>]+)</a>~ig;
print "$_\n" for @link;
}

_ _ D A T A _ _
<A HREF="/pub/databases/transfac/doc/gene1.html#BS" target="_new">BS</A>     -202   -135   <A HREF="/cgi-bin/pub/databases/transfac/getTF.cgi?AC=R00929">R00929</A>; HS$IFNB_14.
<A HREF="/pub/databases/transfac/doc/gene1.html#BS" target="_new">BS</A>     -167    -94   <A HREF="/cgi-bin/pub/databases/transfac/getTF.cgi?AC=R00916">R00916</A>; HS$IFNB_01; Binding factors: R2 <A HREF="/cgi-bin/pub/databases/transfac/getTF.cgi?AC=T00712">T00712</A>.
<A HREF="/pub/databases/transfac/doc/gene1.html#BS" target="_new">BS</A>     -100    -61   <A HREF="/cgi-bin/pub/databases/transfac/getTF.cgi?AC=R00917">R00917</A>; HS$IFNB_02; Binding factors: IRF1 <A HREF="/cgi-bin/pub/databases/transfac/getTF.cgi?AC=T00422">T00422</A>, IRF-2
<A HREF="/pub/databases/transfac/doc/gene1.html#BS" target="_new">BS</A>     <A HREF="/cgi-bin/pub/databases/transfac/getTF.cgi?AC=T00425">T00425</A>.


Ausgabe:

Code: (dl )
1
2
3
4
5
6
R00929
R00916
T00712
R00917
T00422
T00425


Die wichtige Zeile ist diese:

my @link = grep {$_ =~ /^[RT]\d+$/} $html =~ m~<a\s[^>]+>([^<>]+)</a>~ig;

Der rote Teil extrahiert alle Linksbeschreibungen, der blaue stellt sicher, dass nur die aufbewart werden, die Du haben willst (beginnend mit R oder T und dann folgen nur Ziffern).

Natürlich kann man das auch in einem RE zusammenfassen, wie Renee gezeigt hat:

my @link = $html =~ m~<a\s[^>]+>([RT]\d+)</a>~ig;\n\n

<!--EDIT|Crian|1089365042-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
<< |< 1 2 >| >> 20 Einträge, 2 Seiten



View all threads created 2004-07-09 12:20.