Examen PERL is aan de PC, ongeveer 5 uur de tijd en is 1 grote vraag.
Vergelijken strings is met de keywords "eq", "ne", "le", "lt", "ge", "gt"
vb:
if ("beer" eq "test") {
}
@T=()
Scalaire context tabel = element count
Als we lijst maken met [] dan gaat dit een pointer naar een tabel teruggeven.
# Put pointer in the KEY value
$H{"KEY"}=["","",""]
Het nemen van een pointer is een \
in perl.
vb:
@T=()
$h = \T;
Dit print een verwijzing naar een adres zoals ARRAY(0x151f1e4)
.
Om nu de inhoud naar deze tabel te krijgen gaan we dit dereferencen, dit doen we met een { ... }
, voor dit staat een type, zoals: ${...}
of @{...}
.
# Init value on anonymous array unless it is already set!
$M{$k} = [] unless $M{k}
push @{$M{$key}}, $element;
push @values, ${$data->{$_}};
echter mogen we deze ook gewoon weglaten, zoals we met multi dimensionale tabellen zouden doen.
We hebben een globale variabele @ARGV
welke de startup parameters meegeeft, dus voor een file mee te geven doen we bv: perl test.pl helloworld.txt
, om deze nu in te lezen gebruiken we:
while (<>) {
chomp; # avoid \n on last field
}
Ook kunnen we de @ARGV
array manueel zetten:
@ARGV=("__", "__", "__")
# of
@ARGV=glob("*.txt")
while (<>) {
# Get lijn via $_
}
we kunnen ook __DATA__
gebruiken onderaan onze file als input:
while (<DATA>) {
}
__DATA__
Line1
Line2
Line3
...
Diamond operator in lijst context, dit gaat alle lijnen in array inlezen:
$/="";
@T=<>;
print 0 + @T;
VB in Read/Write:
@ARGV=("test.txt");
$^I = ".bak";
while (<>) {
print "LOOOOL";
}
De print gaat hier elke keer de ingelezen lijn veranderen door wat er geprint wordt.
<>
is in READ mode!, kan gezet worden in WRITE als $^I=".bak", dan gaat diamond dit bestand openen in RW mode, dit gaat ook een backup bestand maken.
$ARGV
wordt altijd gezet op het bestand dat we nu aan het verwerken zijn
$.
Lijn nummer waar we zitten bij het inlezen tijdens while(<>)
$/
als we deze veranderen op$/=""
dan gaan we blok per blok inlezen (dus per paragraaf). Als weundef $/
gebruiken, gaan we alle whitespaces wegdoen (ook \n, ...)
De cmp
operator geeft -1, 0 of 1 terug naar gelang de sorteer volgorde, de alias hiervoor is: <=>
sort { (length($a) <=> length($b)) || (lc($a) cmp lc($b)) }
of
sort { length($a) <=> length($b) or lc($a) cmp lc($b) }
@X=<>;
print
sort { (split /:/,$a)[3] <=> (split /:/, $b)[3] }
@X;
__DATA__
nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false
root:*:0:0:System Administrator:/var/root:/bin/sh
daemon:*:1:1:System Services:/var/root:/usr/bin/false
Dit kan sneller met referenties, want als we dit doen zoals voorgaande methode krijgen we een n log(n) uitvoeringstijd.
@X=<>;
print
map { $_->[-1] } # Join de anonieme tabel om origineel te bekomen
sort { $a->[3] <=> $b->[3] } # Sorteer deze anonieme tabel
map { [(split /:/, $_),$_] } # Splits en steek in anonieme tabel
@X;
__DATA__
nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false
root:*:0:0:System Administrator:/var/root:/bin/sh
daemon:*:1:1:System Services:/var/root:/usr/bin/false
my %H{...}; # Create hash
exists $H{...}; # Check if hash exists
delete $H{...}; # Delete hash
$H{} = ""; # Set value of hash
keys %H; # Get the keys of the hash
$H{$_} undef for @T; # For every element in array T, delete the hash keys
# For every key in array
foreach $key (keys %ENV) {
print $key, '=', $ENV{$key}, "\n";
}
> Een hash geinit met array gaat het laatste element tonen bij een print.
# Getting word appearance
$H{lc($_)}++ for @T; # Count the word appearance
print join(" ", map{"$_ : $H{$_}"} sort {$a cmp $b} keys %H; # Print counts of words appearance
Een anonieme hash wordt voorgesteld door {...}
, zo kunnen we bijvoorbeeld een hash in een hash aanmaken.
$M{$key} = {} unless $M{$key};
for $i (1..5) {
$newString .= " ";
}
Overlopen elke key value in hashmap:
while (($key,$value)=each %H) {
}
Karakter | Betekenis |
---|---|
. | Any character except newline. |
. | A period (and so on for *, (, \, etc.) |
^ | The start of the string. |
$ | The end of the string. |
\d,\w,\s | A digit, word character [A-Za-z0-9_], or whitespace. |
\D,\W,\S | Anything except a digit, word character, or whitespace. |
[abc] | Character a, b, or c. |
[a-z] | a through z. |
[^abc] | Any character except a, b, or c. |
aa | bb | Either aa or bb. |
? | Zero or one of the preceding element. |
* | Zero or more of the preceding element. |
+ | One or more of the preceding element. |
{n} | Exactly n of the preceding element. |
{n,} | n or more of the preceding element. |
{m,n} | Between m and n of the preceding element. |
??,*?,+?,{n}?, etc. | Same as above, but as few as possible. |
(expr) | Capture expr for use with \1, etc. |
(?:expr) | Non-capturing group. |
(?=expr) | Followed by expr. |
(?!expr) | Not followed by expr. |
Gebruik split met regex als er een delimiter gebruikt wordt.
Voorbeeld:
@T = split(/.../, $string);
Split kan ook gebruikt worden om gemakkelijk te splitten op spaties zonder dat het eerste element een spatie bevat. (Dus eigenlijk eerst een trim om leading en trailing spatie te verwijderen.).
@T = split("", $string);
Als we een lege string meegeven dan gaan we elk karakter als element beschouwen
@T = split("", $string);
Stel dat we de delimiter zelf niet willen kwijtspelen,
We hebben letters die we na een regex kunnen zetten, dit gaat bepaalde flags enablen.
Flag | Betekenis |
---|---|
i | Ignore casing |
x | Allow commentaar, negeert alle whitespace en alles achter een / |
m | Gaat men $ en ^ nemen per lijn, of globaal? zonder m, 1 keer met m n keer. |
s | Stel multiline, en er staat een . in de regex, dan gaat s \n accepteren als willekeurig karakter! |
g | Onthoud positie in een string |
c | Reset de positie niet na een gefaalde zoek. |
if ($var ~= m/.../) {
}
als we ()
(groups) gebruiken in onze regex, dan geraken we hier aan in perl door $1
, $2
, $3
, $4
te gebruiken.
if ($var ~= m/.../) {
($w,$x,$y,$z) = ($1,$2,$3,$4);
}
@T = $var ~= m/()()()/...;
We kunnen een ~
laten parsen bij de open
functie door gebruik te maken van glob()
.
open(FH, glob("~joebob/somefile")) || die "Couldn't open file: $!";
Voor substitute gaan we onze regex laten voorafgaan door een s
i.p.v. een m
.
vb:
s/regex/vervangstring/modifiers
We kunnen groups gebruiken in de vervangstring door $1, $2, $3 te plaatsen.
de modifier c
heeft hier geen nut. Maar hier hebben we de e
modifier, als we deze gebruiken, dan gaat de vervangstring niet letterlijk geinterpreteerd worden maar als code geinterpreteerd worden.
Speciaal is dat we bv voorkomens van een bepaalde string kunnen nagaan door een regex, s/(...)/%H{$1}++;$1/e
, het eerste stuk is de code, het tweede de vervangstring.
^ gaat kijken dat er links niets matched, $ gaat rechts kijken.
\b
gaat zowel in toekomst als verleden kijken.
vb:
Expressie | Uitleg |
---|---|
(?= ) | Positive Lookahead. Matches a group after the main expression without including it in the result. |
(?! ) | Negative Lookahead. Specifies a group that can not match after the main expression. If it matches, it is discarded from the result. |
(?<= ) | Positive Lookbehind. |
(?<! ) | Negative Lookbehind. |
(?= )
Deze gaat kijken of dit bestaat, en gaat pas verder als het er aan voldoet. Als het er niet aan mag voldoen gebruiken we:
(?! )
voor in het verleden te gaan kijken:
(?<= )
(?<! )
deze laatste 2 gaan geen sterren kunnen gebruiken maar enkel vaste waardes.
Interessante reeksen van regex quiz: abba, prime, order, longcount, a man a plan, backrefs, four
m/^(?!.*(.)(.)\2\1)/
m/^(?!.*[f-z].*e)(?!.*[^a].*a)/
m/^(?!.*([01]{4}).*\1)/
m/^(?!(xx+)\1+$)/
m/^(.)(.).*\2\1$/
- Verwijder alles dat voor de laatste match van
w$
- Vind alles dat eindigt op m en l (koppels)
- x en y waarde 'm' en x en y waarde 'l'
- Maak hash met X waarden en hash met Y waarden (Gesorteerde keys)