Regular Expression Perl/Oneliners
Contents
Capture
Eksempel 1
my $txt ="4-11-2009";
my @array;
$txt =~ /(\d+)-(\d+)-(\d+)/;
$array[0] = $1; # Dato
$array[1] = $2; # Maaned
$array[2] = $3; # Aarstal
er det samme som
my $txt ="4-11-2009";
my @array;
@array = $txt =~ /(\d+)-(\d+)-(\d+)/;
Links
One-liners
confusing eksempel 1
Onelineren nedenunder finder i alle filer som hedder .txt som extension steder hvor der står Fahrenheit temperaturer - fx. 56F - og udskifter dem med Celcius temperaturer - fx. 12C. Temperaturen omregnes med formlen Celsius = (Fahrenheit - 32) * 5/9
perl -pi -e 's{([-+]?\d+(\.d*)?)F\b}{sprintf "%.0fC",($1-32)*5/9}eg' *.txt
perl aktivering
Progammet startes med perl -pi -e 'ONELINER' hvor (Se hvid tekst i eksemplet herunder)
- perloption p = Loop One-liner og indlæs filer linie for linie *.txt
- Svarer til "while (<>) { ... }" omkring din One-liner.
- perloption i = Editer filer direkte
- perloption e = programlinie eller One-liner.
<input>perl -pi -e </input>'s{([-+]?\d+(\.d*)?)F\b}{sprintf "%.0fC",($1-32)*5/9}eg' <input>*.txt</input>
Search and replace
Eksemplet ovenfor anvender search and replace funktionen s/PATTERN/REPLACE/ som også kan skrives s{PATTERN}{REPLACE}. Se herunder.
perl -pi -e '<input>s{</input>([-+]?\d+(\.d*)?)F\b<input>}{</input>sprintf "%.0fC",($1-32)*5/9<input>}</input><notice>eg</notice>' *.txt
Search and replace funktionen anvender options e og g. Se med blåt ovenfor
- Option e = Betragt REPLACE delen af searchfunktionen som et Perl expression - altså som program og ikke tekst. (sprintf funktionen)
- Option g = global. Erstat alle der matcher. Ikke kun en gang.
Søge pattern
Mønstret der søges efter i filerne - linie for linie - er ([-+]?\d+(\d+(\.d*)?)F\b Se herunder.
perl -pi -e 's{<input>([-+]?\d+(\.d*)?)F\b</input>}{sprintf "%.0fC",($1-32)*5/9}eg' *.txt
Der ledes i linerne efter Fahrenheit grader skriver som for eksempel 12F, +12F, -12F, +12.123F og den numeriske del huskes. Altså ved +12.12F huskes +12.42.
Paranteserne i pattern
I Eksemplet herunder ses to måder at anvende paranteser på.
- De hvide paranteser er anvendt som capture, altså det der matcher inde i de hvide paranteser skal huskes hvis der står et F for fahrenheit bagefter.
- De blå paranteser anvendes som grouping. Det kan ses ved at der anvendes ? lige efter som betyder at det i de blå paranteser kan ske 0 eller 1 gang. (Enten er der decimaler i gradantallet eller også er der ikke.)
perl -pi -e 's{<input>(</input>[-+]?\d+<notice>(</notice>\.d*<notice>)</notice><error>?</error><input>)</input><error>F</error>\b}{sprintf "%.0fC",($1-32)*5/9}eg' *.txt
Selve søgemønsteret
perl -pi -e 's{<notice>(</notice><input>[-+]?\d+(\.d*)?<notice>)</notice>F\b</input>}{sprintf "%.0fC",($1-32)*5/9}eg' *.txt
Alt hvad der matcher mellem de blå paranteser huskes som $1.
- [-+]? = tegnet - (minus) eller + kan stå 0 eller 1 gang.
- \d+ = Der skal stå mindst et ciffer \d er ciffer + er en eller flere af forrige - altså cifferet.
- (\.d*)? = Der kan være decimaler.
- F\b = Der skal stå et stort F for fahrenheit og det skal være på en ordgrænse \b. Altså ikke flere tegn
Erstat pattern
Når søgningen matcher vil erstat delen udføres. Se hvid tekst nedenunder. Modifierne med blå tekst betyder eat erstat feltet er et perl expression som skal udføres og ikke bare tekst der skal erstattes med. g betyder globally at søg/erstat skal være global på linien.
perl -pi -e 's{([-+]?\d+(\.d*)?)F\b}{<input>sprintf "%.0fC",($1-32)*5/9</input>}<notice>eg</notice>' *.txt
perl expression i erstat pattern
Funktionen sprintf udføres med "%.0fC" hvilket betyder at der skal udskives et flydende decimaltal med 0 decimaler efterfulgt af et C for celsius. Efter kommaet står der ($1-32)*5/9 hvor $1 er temperaturen i Fahrenheit husket fra Pattern delen. det mellem de blå paranteser herunder. Formel Celsius = (Fahrenheit - 32) * 5/9 udføres og erstatter Fahrenheit tallet i filerne.
perl -pi -e 's{<notice>(<input>[-+]?\d+(\.d*)?</input>)</notice>F\b}{<input>sprintf "%.0fC",(<notice>$1</notice>-32)*5/9</input>}eg' *.txt