/ Forside / Teknologi / Udvikling / Perl / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Perl
#NavnPoint
bjarneA 141
poul_from 50
soccer 30
Nicknack 14
Tmpj 0
Stack size og regulære udtryk
Fra : Adam Sjøgren


Dato : 21-06-04 12:47

Hej.


Jeg er lige stødt ind i følgende sjove problem:

$ perl -e '$text="!"x31000; $text=~s/(.)\1{20,}//;'
Segmentation fault
$

(sker både med 5.6.1 og 5.8.4; antal tegn der skal til varierer).

En søgning på rt.perl.org afslørede at når tilsvarende segmentation faults
rapporteres, er svaret at perl er løbet tør for stak-plads, og ganske rigtigt:

$ ulimit -s 20000
$ perl -e '$text="!"x31000; $text=~s/(.)\1{20,}//;'
$

Da jeg ikke selv bestemmer over $text i ikke-nedbarberede, ikke-eksempel
tilfælde, så dur den løsning desværre ikke, så jeg må finde på noget andet.

Hvad plejer I at gøre?

.... og er det ikke lidt grimt at den bare giver en segmentation fault?


Mvh.

Adam

--
"Från och med nu så är 'så snart som möjligt' 53 Adam Sjøgren
timmar!" asjo@koldfront.dk

 
 
Adam Sjøgren (21-06-2004)
Kommentar
Fra : Adam Sjøgren


Dato : 21-06-04 13:25

Adam Sjøgren wrote:

> $ perl -e '$text="!"x31000; $text=~s/(.)\1{20,}//;'

[...]

> Hvad plejer I at gøre?

Her er hvad jeg fik bakset sammen i stedet. Elegant? Nej. Virker? Tjoh, måske.

my $i=0;
my $l='';
my $same=0;
my $out='';
$len--;
for($i=0; $i<length($text); $i++) {
my $t=substr($text, $i, 1);
if ($t eq $l) {
$same++;
}
else { # End of repetition:
if ($same>=$len) { # Contract:
$out.='...';
$out.=$t;
}
else {
$out.=$l x $same;
$out.=$t;
}
$same=0;
}
$l=$t;
}

$text=$out;


Mvh.

--
"Från och med nu så är 'så snart som möjligt' 53 Adam Sjøgren
timmar!" asjo@koldfront.dk

Lasse Hillerøe Peter~ (25-06-2004)
Kommentar
Fra : Lasse Hillerøe Peter~


Dato : 25-06-04 14:30

In article <cb6hr8$qva$1@hq.szn.dk>, Adam Sjøgren <asjo@koldfront.dk>
wrote:

> Hej.
>
>
> Jeg er lige stødt ind i følgende sjove problem:
>
> $ perl -e '$text="!"x31000; $text=~s/(.)\1{20,}//;'
> Segmentation fault
> $
>
> (sker både med 5.6.1 og 5.8.4; antal tegn der skal til varierer).
>
> En søgning på rt.perl.org afslørede at når tilsvarende segmentation faults
> rapporteres, er svaret at perl er løbet tør for stak-plads, og ganske rigtigt:
>
> $ ulimit -s 20000
> $ perl -e '$text="!"x31000; $text=~s/(.)\1{20,}//;'
> $
>
> Da jeg ikke selv bestemmer over $text i ikke-nedbarberede, ikke-eksempel
> tilfælde, så dur den løsning desværre ikke, så jeg må finde på noget andet.
>
> Hvad plejer I at gøre?
>
> ... og er det ikke lidt grimt at den bare giver en segmentation fault?

Joh, men mon ikke problemet er noget med den måde Perl opbygger og
bruger regexp'et, som resulterer i en uheldig opførsel? Jeg kan
forestille mig at brugen af backreference kombineret med
iterations-grænser medfører en kombinatorisk eksplosion af en art?

Da det er gentagne successive forekomster af et enkelt - vilkårligt -
tegn du vil erstatte med "...", kunne det være smart i stedet at putte
det ind i en foreach:

for $i (map { chr } (32 .. 255)) { $text =~ s/$i{20,}/$i.../ }

Afhængigt af om du bare vil slette eller indsætte en art ellipse, kan
det nok være en god ide at overveje rækkefølgen af tegnene. Fx med "..."
ellipsen var det sikkert en god ide at starte med ".", ellers kunne man
principielt risikere en fejlagtig dobbeltreduktion i sjældne
specialtilfælde, hvor gentagne gentagelser reduceres en enkelt ellipse.

Nåja, og så er der regex specialtegnene, som vist skal håndteres med en
eller anden option til s///.

Jeg er ret sikker på at Friedls _Mastering Regular Expressions_ kan
oplyse om årsagen til stakfejlen, men jeg har den ikke selv på hylden.

-Lasse

Adam Sjøgren (25-06-2004)
Kommentar
Fra : Adam Sjøgren


Dato : 25-06-04 17:45

On Fri, 25 Jun 2004 15:30:22 +0200, Lasse wrote:

> for $i (map { chr } (32 .. 255)) { $text =~ s/$i{20,}/$i.../ }

Det er godt nok lidt mere læseligt end det jeg endte med at lave, men
ikke særligt pænt, synes jeg (meget unødvendigt arbejde).

Gad vide hvad der er hurtigst?


Mvh.

--
"Vejen ender, bålet brænder Adam Sjøgren
Det brænder for dig, Alexander" asjo@koldfront.dk

Lasse Hillerøe Peter~ (26-06-2004)
Kommentar
Fra : Lasse Hillerøe Peter~


Dato : 26-06-04 11:42

In article <87fz8jh9jd.fsf@koldfront.dk>,
asjo@koldfront.dk (Adam Sjøgren) wrote:

> On Fri, 25 Jun 2004 15:30:22 +0200, Lasse wrote:
>
> > for $i (map { chr } (32 .. 255)) { $text =~ s/$i{20,}/$i.../ }
>
> Det er godt nok lidt mere læseligt end det jeg endte med at lave, men
> ikke særligt pænt, synes jeg (meget unødvendigt arbejde).
>
> Gad vide hvad der er hurtigst?

Det er jo dig der har behovet - så det må være dig der poster
benchmarken...

(Spøg til side, jeg skal til at pakke til ferie, så jeg når det ikke.)

-Lasse

Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408914
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste