Skip to content

Instantly share code, notes, and snippets.

@XavierGeerinck
Created September 30, 2015 15:09
Show Gist options
  • Save XavierGeerinck/ce625b0becb513c21b16 to your computer and use it in GitHub Desktop.
Save XavierGeerinck/ce625b0becb513c21b16 to your computer and use it in GitHub Desktop.

Reeks 1

Examen

Examen PERL is aan de PC, ongeveer 5 uur de tijd en is 1 grote vraag.

Vergelijken strings

Vergelijken strings is met de keywords "eq", "ne", "le", "lt", "ge", "gt"

vb:

if ("beer" eq "test") {
}

Tabel

@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"}=["","",""]

Pointers Perl (references)

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 @{...}.

Declareren array tijdens while van een map

# Init value on anonymous array unless it is already set!
$M{$k} = [] unless $M{k}

toevoegen elk element:

push @{$M{$key}}, $element;

Het dereferencen gebeurt veel, we kunnen dit echter vervangen door een ->

push @values, ${$data->{$_}};

echter mogen we deze ook gewoon weglaten, zoals we met multi dimensionale tabellen zouden doen.

Inlezen data

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 we undef $/ gebruiken, gaan we alle whitespaces wegdoen (ook \n, ...)

Schrijven data

CMP Operator

De cmp operator geeft -1, 0 of 1 terug naar gelang de sorteer volgorde, de alias hiervoor is: <=>

Sorteren op meerdere criteria

sort { (length($a) <=> length($b)) || (lc($a) cmp lc($b)) }

of

sort { length($a) <=> length($b) or lc($a) cmp lc($b) }

Sneller sorteren ingelezen data

Op basis van 4de veld:

@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

Sneller op basis van 4de veld

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

Hashes

Normale hashes

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

Anonieme hashes

Een anonieme hash wordt voorgesteld door {...}, zo kunnen we bijvoorbeeld een hash in een hash aanmaken.

$M{$key} = {} unless $M{$key};

For operators

for $i (1..5) {
	$newString .= " ";
}

While

Overlopen elke key value in hashmap:

while (($key,$value)=each %H) {
}

Reeks 2

Reguliere expressies

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.

Oplossen met regexes

Split

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,

Regex modifiers

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.

Checken op regex

Scalaire context

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);
}

Lijst Context

@T = $var ~= m/()()()/...;

Tricks

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: $!";

Substitute

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.

^ en $

^ 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

Abba

m/^(?!.*(.)(.)\2\1)/

Order

m/^(?!.*[f-z].*e)(?!.*[^a].*a)/

Long Count

m/^(?!.*([01]{4}).*\1)/

Prime

m/^(?!(xx+)\1+$)/

A man, a plan

m/^(.)(.).*\2\1$/

Reeks 3

PDF Parsing (Zie oef 16)

  1. Verwijder alles dat voor de laatste match van w$
  2. Vind alles dat eindigt op m en l (koppels)
  3. x en y waarde 'm' en x en y waarde 'l'
  4. Maak hash met X waarden en hash met Y waarden (Gesorteerde keys)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment