Schrift
[thread]6077[/thread]

Reguläre Ausdrücke durch anderes ersetzten...

Leser: 2


<< |< 1 2 3 4 ... 6 >| >> 60 Einträge, 6 Seiten
ppm1
 2004-02-16 23:16
#80102 #80102
User since
2003-09-14
142 Artikel
BenutzerIn
[default_avatar]
Hallo

man sage mir das das suchen mit regulären Ausdrücken sehr Serverintensiv sei?

Auf alle Fälle, stellen wir uns mal folgende sache vor:

ein user gibt in ein Formular etwas ein:


1. Problem
Das kommt in die Variable $rein
Dann wird mit Regulären ausdrücken geschaut

if ($rein =~ /+/ or $rein=~ /-/ usw....){FEHLER}
(Es wird nach ner handvoll bestimmter zeichen geschaut)


Wie kann ich diese dort umgehen.


2. Problem

In der Variablen sollen nur Zahlen sein:

if ($rein =~ /\D/){Fehler}
Wie kann ich das besser lösen?
Ronnie
 2004-02-16 23:37
#80103 #80103
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Wie wäre es mit:
Code: (dl )
&fehler() unless ($rein =~ m/^\d+$/);
Ishka
 2004-02-16 23:50
#80104 #80104
User since
2003-08-04
771 Artikel
HausmeisterIn
[Homepage] [default_avatar]
Das Suchen mit regulären Ausdrücken ist sehr Rechenleistungsintensiv im Vergleich zum Addieren von zwei Zahlen. Aber es ist effizienter mit regulären Ausdrücken zu suchen, als mit sonst irgendetwas. Was langsam ist, ist daß reguläre Ausdrücke manchmal den ganzen string auswerten müssen. (und das g-Flag senkt die Geschwindigkeit natürlich deutlich - falls du es nicht brauchst. Falls du es doch brauchst, ist es allerdings meist die schnellste Lösung das über nen RegEx zu lösen).

Reguläre Ausdrücke sind in der Tat schneller, als man meist denkt - insbesondere ist die RegEx-Engine in Perl sehr hoch entwickelt.

Wenn dein Regulärer Ausdruck die Gestalt /sdfajk fads awefölk/ (langer konstanter Text, einige Zeichen darin mehrfach) hat, oder das zumindestens drin vorkommt, dann wird idR. nichteinmal jedes Zeichen des Strings abgefragt. Also ist /blahagd(?:miau|blubb)fdsjksanf/ auf jeden Fall schneller als /blahagd.*?fdsjksanf/

Allerdings sollte man sich darüber auch nicht alzu viele Gedanken machen - so knapp ist die Rechenleistung meist doch nicht bemessen.
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}
Ishka
 2004-02-16 23:59
#80105 #80105
User since
2003-08-04
771 Artikel
HausmeisterIn
[Homepage] [default_avatar]
Ronnies code ist tatsächlich um etwa den Faktor drei schneller (auf meinem Rechner zumindestens). Ich hätte vor der Messung fast darauf gewettet gehabt, daß der langsamer ist... Sachen gibts.
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}
Ishka
 2004-02-17 00:15
#80106 #80106
User since
2003-08-04
771 Artikel
HausmeisterIn
[Homepage] [default_avatar]
Nach längerem Testen:
umso kürzer der String, umso mehr wird ppm1s Methode (relativ gesehen) schneller.
umso fälscher der String, umso mehr gewinnt Ronnies Methode an Tempo.
Allerdings ist auch bei ner einstelligen Zahl Ronnies Methode schneller (wenn auch nur ca. Faktor 1,5).

Ok, jetzt hört der wissensteil auf und meine Vermutungen fangen an:
Ich denke, daß dadurch, daß ne feste Startmarke gesetzt wird der Anfangszähler nicht verändert wird, was einen Teil des Unterschieds ausmachen könnte.
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}
Strat
 2004-02-17 00:22
#80107 #80107
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
[quote=ppm1,16.02.2004, 22:16]man sage mir das das suchen mit regulären Ausdrücken sehr Serverintensiv sei?[/quote]
ja, das stimmt
nein, das ist bloedsinn

das haengt davon ab, was man sucht; wenn man genau eine fixe zeichenkette in einer laengeren sucht, dann ist index (oder rindex) haeufig schneller. wenn man komplexere sachen sucht, dann ist ein regulaerer ausdruck oft schneller als mehrere aufrufe von index

bei regulaeren ausdruecken sollte man, wenn moeglich, auf flags wie /i verzichten, weil dadurch einiges an optimierungsmoeglichkeiten verloren geht, und die regex-engine deshalb nicht besonders effektiv arbeiten kann.

wenn moeglich, sollte man auch anker ^ und $ verwenden.

/abc(?:def|geh)/ ist meistens schneller als (?:abcdef|abcgeh)/

capturing nur dort, wo es noetig ist, also nicht (ab|cd), wenn man abcde spaeter nicht mehr braucht, sondern (?:ab|cd)

wenn nur a oder b gross oder klein sein koennen, dann besser
(?i:a|b) oder besser noch [aAbBc-z] matchen

die variablen $& $` $&acute; sollte man nicht verwenden, weil die immer noch recht viel laufzeit kosten koennen

die option /o kann auch ganz schoen geschwindigkeit bringen
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
Ishka
 2004-02-17 00:27
#80108 #80108
User since
2003-08-04
771 Artikel
HausmeisterIn
[Homepage] [default_avatar]
was macht /o - in perlre hab ich das nicht gefunden.
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}
Strat
 2004-02-17 01:01
#80109 #80109
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
/o ist ein Versprechen an Perl, dass es die Regex immer wieder ohne Neucompilierung verwenden kann, also dass sich die regex (z.B. in einer Schleife) nie aendert. das spielt eigentlich nur eine rolle, wenn darin variablen vorkommen, z.B.
Code: (dl )
1
2
3
4
$regex = "^abcde";
while (<LOG>) {
 print if /$regex/;
}

hier wird das Muster if /$regex/ bei jedem lauf neu uebersetzt (bzw. bei neueren Perlversionen nicht mehr voellig, sondern es wird nur noch ueberprueft, ob es sich geaendert hat). da sich $regex jedoch nie aendert, kann man da bedenkenlos if /$regex/o schreiben, und es gibt einen geschwindigkeitsgewinn. falls sich $regex doch mal aendern sollte, hat man natuerlich pech gehabt...\n\n

<!--EDIT|Strat|1076972650-->
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
Ishka
 2004-02-17 01:22
#80110 #80110
User since
2003-08-04
771 Artikel
HausmeisterIn
[Homepage] [default_avatar]
Cool - danke
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}
ppm1
 2004-02-17 15:32
#80111 #80111
User since
2003-09-14
142 Artikel
BenutzerIn
[default_avatar]
[quote=Ronnie,16.02.2004, 22:37]Wie wäre es mit:
Code: (dl )
&fehler() unless ($rein =~ m/^\d+$/);
[/quote]
könnte ich auch statt dessen schreiben:

if (not($rein =~m/^\d+$/)){FEHLER}
else {
RICHTIG
}


oder ist das belastender.

Noch ne Frage dazu: was bedeute das ^ genau und das +$?
<< |< 1 2 3 4 ... 6 >| >> 60 Einträge, 6 Seiten



View all threads created 2004-02-16 23:16.