Difference between revisions of "Regular Expression Perl/Oneliners"

From Teknologisk videncenter
Jump to: navigation, search
m (perl aktivering)
m
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
 +
= Capture =
 +
== Eksempel 1 ==
 +
<source lang=perl>
 +
my $txt ="4-11-2009";
 +
my @array;
 +
$txt =~ /(\d+)-(\d+)-(\d+)/;
 +
 +
$array[0] = $1; # Dato
 +
$array[1] = $2; # Maaned
 +
$array[2] = $3; # Aarstal
 +
</source>
 +
er det samme som
 +
<source lang=perl>
 +
my $txt ="4-11-2009";
 +
my @array;
 +
@array = $txt =~ /(\d+)-(\d+)-(\d+)/;
 +
</source>
 
= Links =
 
= Links =
 
*[[Media:Regexp Quick Reference.pdf|Regular Expression Quick Reference Guide]]
 
*[[Media:Regexp Quick Reference.pdf|Regular Expression Quick Reference Guide]]
 
*[http://www.regextester.com Regular Expression test web-site]
 
*[http://www.regextester.com Regular Expression test web-site]
 
= One-liners =
 
= One-liners =
==confusing==
+
==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.
+
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'''
 
<source lang=cli>
 
<source lang=cli>
 
perl -pi -e 's{([-+]?\d+(\.d*)?)F\b}{sprintf "%.0fC",($1-32)*5/9}eg' *.txt
 
perl -pi -e 's{([-+]?\d+(\.d*)?)F\b}{sprintf "%.0fC",($1-32)*5/9}eg' *.txt
 
</source>
 
</source>
=== Forklaring ===
+
=== perl aktivering ===
==== perl aktivering ====
 
 
Progammet startes med '''perl -pi -e 'ONELINER'''' hvor (Se hvid tekst i eksemplet herunder)
 
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'''
 
*perloption p = Loop One-liner og indlæs filer linie for linie '''*.txt'''
 
** Svarer til '''"while (<>) { ... }"''' omkring din One-liner.
 
** Svarer til '''"while (<>) { ... }"''' omkring din One-liner.
*perloption = Editer filer direkte
+
*perloption i = Editer filer direkte
*perloption = programlinie eller One-liner.
+
*perloption e = programlinie eller One-liner.
 
<source lang=cli>
 
<source lang=cli>
 
<input>perl -pi -e </input>'s{([-+]?\d+(\.d*)?)F\b}{sprintf "%.0fC",($1-32)*5/9}eg' <input>*.txt</input>
 
<input>perl -pi -e </input>'s{([-+]?\d+(\.d*)?)F\b}{sprintf "%.0fC",($1-32)*5/9}eg' <input>*.txt</input>
 
</source>
 
</source>
  
==== Search and replace ====
+
=== Search and replace ===
 
Eksemplet ovenfor anvender search and replace funktionen '''s/PATTERN/REPLACE/''' som også kan skrives '''s{PATTERN}{REPLACE}'''. Se herunder.
 
Eksemplet ovenfor anvender search and replace funktionen '''s/PATTERN/REPLACE/''' som også kan skrives '''s{PATTERN}{REPLACE}'''. Se herunder.
 
<source lang=cli>
 
<source lang=cli>
Line 29: Line 45:
 
*Option g = global. Erstat alle der matcher. Ikke kun en gang.
 
*Option g = global. Erstat alle der matcher. Ikke kun en gang.
  
==== Søge pattern ====
+
=== Søge pattern ===
 
Mønstret der søges efter i filerne - linie for linie - er '''([-+]?\d+(\d+(\.d*)?)F\b''' Se herunder.
 
Mønstret der søges efter i filerne - linie for linie - er '''([-+]?\d+(\d+(\.d*)?)F\b''' Se herunder.
 
<source lang=cli>
 
<source lang=cli>
Line 36: Line 52:
  
 
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.
 
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 =====
+
==== Paranteserne i pattern ====
 
I Eksemplet herunder ses to måder at anvende paranteser på.  
 
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 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.)
 
*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.)
 
<source lang=cli>
 
<source lang=cli>
perl -pi -e 's{<input>(</input>[-+]?\d+<notice>(</notice>\.d*<notice>)</notice><error>?</error><input>)</input>F\b}{sprintf "%.0fC",($1-32)*5/9}eg' *.txt
+
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
 
</source>
 
</source>
===== Selve søgemønsteret =====
+
 
 +
==== Selve søgemønsteret ====
 
<source lang=cli>
 
<source lang=cli>
 
perl -pi -e 's{<notice>(</notice><input>[-+]?\d+(\.d*)?<notice>)</notice>F\b</input>}{sprintf "%.0fC",($1-32)*5/9}eg' *.txt
 
perl -pi -e 's{<notice>(</notice><input>[-+]?\d+(\.d*)?<notice>)</notice>F\b</input>}{sprintf "%.0fC",($1-32)*5/9}eg' *.txt
 
</source>
 
</source>
 
Alt hvad der matcher mellem de blå paranteser huskes som '''$1'''.
 
Alt hvad der matcher mellem de blå paranteser huskes som '''$1'''.
*'''[-+]?''' = tegnet + eller - kan stå 0 eller 1 gang.
+
*'''[-+]?''' = 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 skal stå mindst et ciffer '''\d''' er ciffer '''+''' er en eller flere af forrige - altså cifferet.
 
*'''(\.d*)?''' = Der kan være decimaler.
 
*'''(\.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
 
*'''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 ====
+
 
 +
=== Erstat pattern ===
 
Når søgningen matcher vil erstat delen udføres. Se hvid tekst nedenunder. Modifierne med blå tekst betyder ''e''at 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.
 
Når søgningen matcher vil erstat delen udføres. Se hvid tekst nedenunder. Modifierne med blå tekst betyder ''e''at 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.
 
<source lang=cli>
 
<source lang=cli>
 
perl -pi -e 's{([-+]?\d+(\.d*)?)F\b}{<input>sprintf "%.0fC",($1-32)*5/9</input>}<notice>eg</notice>' *.txt
 
perl -pi -e 's{([-+]?\d+(\.d*)?)F\b}{<input>sprintf "%.0fC",($1-32)*5/9</input>}<notice>eg</notice>' *.txt
 
</source>
 
</source>
===== perl expression i erstat pattern =====
+
==== perl expression i erstat pattern ====
Funktionen [[sprintf]] udefø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 -
+
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.
32) * 5/9 udføres og erstatter Fahrenheit tallet i filerne.
 
 
<source lang=cli>
 
<source lang=cli>
 
perl -pi -e 's{<notice>(<input>[-+]?\d+(\.d*)?</input>)</notice>F\b}{<input>sprintf "%.0fC",(<notice>$1</notice>-32)*5/9</input>}eg' *.txt
 
perl -pi -e 's{<notice>(<input>[-+]?\d+(\.d*)?</input>)</notice>F\b}{<input>sprintf "%.0fC",(<notice>$1</notice>-32)*5/9</input>}eg' *.txt
 
</source>
 
</source>
  
{{#css:
+
{{Source cli}}
   
 
    pre {  font-weight: bold; font-size: 150%; color: #00FF00; background: black;}
 
}}
 
 
[[Category:Perl]]
 
[[Category:Perl]]

Latest revision as of 17:32, 28 February 2010

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