
Nu har han to problemer...
En af mine venner havde et let problem. I en række filer skulle han fjerne et bestemt afsnit. Hvert afsnit bestod af en linje der startede i begyndelsen af en linje og derefter en række indrykkede linjer. Det lyder jo let, men han var altså ikke gode venner med regulære udtryk, men man måtte kunne gøre det smart.
Det tog mig et par minutter at sætte følgende kodestump sammen:
local $/ = undef;
my $file = <>;
$file =~ s/^\w+\s+FooBar.*'('=^\w)//ms
print $file;
De to første linjer er idiomet for at læse en hel fil ind i $file. Det sjove sker i linje tre. Det begynder let nok, så kommer der en ikke-grådig stjerne og vi slutter af med en "zero width look ahead". Nåja og så lige noget mystisk '/ms' tilsidst.
Alternativt rystede jeg følgende ud ad ærmet:
while(<>) {
$doprint = 1 if /^\w/;
$doprint = 0 if /^\w+\s+FooBar/;
print $_ if $doprint;
}
Hver gang vi ser starten af et afsnit slår vi udskrivning til, men hvis vi ser starten på det afsnit vi vil fjerne slår vi udskrivning fra. Stort set samme mængde kode, men ingen specielle ting ud over helt standard perl-idiomer. Det burde der ikke være de store problemer i at vedligeholde om 14 dage.
Men regulære udtryk er smart! Ja, men ud over at være lettere at vedligeholde, viser en løs benchmark at løsningen med løkken er 3 gange så hurtig hvis jeg isolerer løkken, og 20% hurtigere hvis jeg medtager filhåndtering. (Nej, koden gør ikke helt det samme...)
Men regulære udtryk er smart! Ja, men kun hvis man rent faktisk kan gennemskue hvad de gør uden at gribe til dokumentationen.
Men regulære udtryk er smart! Ja, så lav så mange som overhovedet muligt. Heller to små end et stort.
I 1997 skrev Jamie Zawinski (tidlig Netscape-udvikler) en lang Perl-rant hvor følgende citat stammer fra: 'Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.'
Talemåden er langt ældre og kan bruges om mange ting, for eksempel Tråde, XML og singleton objekter. Altsammen gode værktøjer, men bør ikke bruges ukritisk.
Kommentarer (3)
Jeg vil meget gerne skrive flere indlæg af denne stil, men jeg har opdaget at det faktisk er svært.
Kodeeksemplerne må ikke blive meget større end her, hverken i kompleksitet eller i breden. Man skal afveje hvor mange specielle perl-konstruktioner man kan tillade sig at bruge. At slurpe en fil kræver en forklaring, at bruge if som statement modifier går nok, men jeg har sikkert skræmt folk med Perl-fobi væk. Hvor meget skal man forklare? Jeg kunne sagtens have pillet det regulære udtryk fra hinanden, så alle kunne forstå det (i et par sekunder).
Og derudover skal man have noget relevant at sige. Jeg vil nødigt ende med noget der "bare" er rodede fragmenter af en lærebog.
Må også lave flere xkcd-referencer...

