\documentclass[screen]{beamer}

\usepackage[T1]{fontenc}
\usepackage[latin1]{inputenc}

\usepackage{beamerthemesplit}

\parindent=0pt
\parskip=0.5\baselineskip

\title{Regex i Perl}
\author{Knut Auvor Grythe}
\date{\today}

\begin{document}

\frame{\titlepage}

%\section[Innhold]{}
%\frame{\tableofcontents}

\section{Introduksjon}
\subsection{Litt om regex}
\frame
{
  	\frametitle{Hva er Regex?}
	
	\begin{itemize}
		\item Forkortelse for ``Regular Expression'' (``regulært uttrykk'' på norsk).
		\item En kjapp og grei måte å gjenkjenne enkle tekst-strukturer på.
		\item Velegnet for å gjenkjenne eller modifisere tekst på et gitt format.
		\item Veldig kompakt syntaks, og dermed lite å skrive.
		\item Kan brukes i de fleste programmeringsspråk (men har ofte litt varierende syntaks)
	\end{itemize}
}

\frame
{
  	\frametitle{Hvordan ser en regex ut?}
	
	\begin{itemize}
		\item En regex er i utgangspunktet bare en tekststreng, der noen få av tegnene har en spesiell betydning. 
		\item I en del språk (for eksempel Perl) skrives regexer med en skråstrek før og etter. 
		\item Denne regexen gjenkjenner teksten ``banan'': /banan/
	\end{itemize}
}

\frame
{
  	\frametitle{Hva gjør den egentlig?}
	
	\begin{itemize}
		\item En regex går gjennom teksten \textit{fra venstre til høyre}, helt til den finner et treff.
		\item En regex er grådig. Om to ulike treff begynner på samme sted i teksten, vil den alltid ta det lengste.
		\item Hva som skjer når regexen matcher noe avhenger av hvordan den er brukt.
	\end{itemize}
}

\subsection{Praktisk bruk}
\frame
{
  	\frametitle{Bruksområder i Perl}
	
	Tre vanlige bruksområder for regex i perl er matching, substitusjon og
	splitting. Det finnes også andre bruksområder, men da er det i praksis
	matching som utføres.

	\begin{block}{Matching}
		if (\$var =\~{} /banan/) \{
			do\_stuff();
		\}
	\end{block}

	\begin{block}{Substitusjon}
		\$var =\~{} s/banan/eple/;
	\end{block}

	\begin{block}{Splitting}
		my @array = split(/a/, ``banan'');
	\end{block}
}

\frame
{
	\frametitle{Hvordan bruke andre tegn enn //}

	Selv om det er standard å skrive regexen inni //, er det fullt lovlig å
	bruke andre tegn i stedet. Dette er kjekt om du skal matche et pattern med
	mange /-er i, og ikke har lyst til å escape alle sammen. 
	
	For at Perl skal kjenne igjen matching må man skrive en ``m'' foran
	uttrykket, dersom man bruker noe annet enn //.

	Det er ganske vanlig å bruke komma eller kolon som tegn.

	\begin{block}{Matching}
		if (\$var =\~{} m,banan,) \{
			do\_stuff();
		\}
	\end{block}

	\begin{block}{Substitusjon}
		\$var =\~{} s,banan,eple,;
	\end{block}

}

\frame
{
	\frametitle{Modifikatorer}
	Modifikatorer er ting du kan skrive bak uttrykket ditt for å få det til å
	oppføre seg litt annerledes. Vi konsentrerer oss om de to viktigste, /g og /i.

	Modifikatorer brukes ved å plassere dem rett bak siste / i utrykket.

	\begin{block}{Eksempler}
	\begin{tabular}{ll}
	\textbf{/abcd/i} & et matche-uttrykk med /i.\\
	\textbf{s/abcd/blarb/g} & et substitusjons-uttrykk med /g.\\
	\textbf{s/abcd/blarb/ig} & et substitusjons-uttrykk med både /g og /i.\\
	\end{tabular}
	\end{block}
}

\frame
{
	\frametitle{Modifikatorer - Hva de gjør}

	Nå som vi vet hvordan vi slenger på en modifikator kan vi kanskje få vite
	hva de gjør også :-)

	\textbf{/i} gjør at uttrykket ikke skiller på store og små bokstaver
	(case-insensitive). Litt tregere enn å bare skrive inn store og små
	bokstaver manuelt, siden den følger gjeldende locale, men neppe noe problem
	i praksis.

	\textbf{/g} brukes kun i substitusjon, og står for ``global''. Vanligvis
	vil substitusjonen bare bytte ut første treff, men med denne vil den bytte
	ut \textit{alle} treff.
}

\frame
{
  	\frametitle{Kommandolinje-testing av matche-uttrykk (``grepping'')}
	
	\begin{block}{Perl}
	echo "vi liker bananer" | perl -ne 'print if /banan/'
	\end{block}
	
	\begin{block}{Andre språk}
	echo "vi liker bananer" | grep 'banan'\newline
	echo "vi liker bananer" | sed -e '/banan/p' -e 'd'\newline
	echo "vi liker bananer" | awk '/banan/ \{print\}'
	\end{block}
	
}

\frame
{
  	\frametitle{Kommandolinje-testing av substitusjons-uttrykk (``sedding'')}
	
	\begin{block}{Perl}
	echo "vi liker bananer" | perl -pe 's/banan/rosin/'
	\end{block}
	
	\begin{block}{Andre språk}
	echo "vi liker bananer" | sed 's/banan/rosin/'\newline
	echo "vi liker bananer" | awk '\{sub(/banan/, "rosin"); print\}'
	\end{block}
	
}

\section{Oversikt over syntaks}
\subsection{Spesielle tegn og hva de gjør}

\frame
{
  	\frametitle{Å matche en helt vanlig tekst-streng}
	
	Om du skal matche en helt vanlig tekst-streng, kan du bare skrive den rett
	ut, som for eksempel /banan/ som vi har sett før.

	\begin{block}{NB!}
	Husk imidlertid at enkelte tegn har spesiell betydning, og disse må escapes
	om du vil ha selve tegnet. Et eksempel på dette er punktum, som kan matches
	med /$\backslash$./.

	Den største forskjellen på de ulike regex-dialektene er hva som skal
	escapes. En del språk tolker alt som tekst, og bruker spesialbetydningen
	når du escaper i stedet. Hva andre språk gjør er imidlertid litt utenfor
	skopet til kurset.
	\end{block}
}

\frame
{
  	\frametitle{Liste over magiske tegn(-sekvenser)}
	
	\begin{tabular}{ll}
           $\backslash$  & Quote the next metacharacter\\
           .  & Match any character (except newline)\\
           *    &  Match 0 or more times\\
           +    &  Match 1 or more times\\
           ?    &  Match 1 or 0 times\\
           \{n\}  &  Match exactly n times\\
           \{n,\} &  Match at least n times\\
           \{n,m\} &  Match at least n but not more than m times\\
           \^{} &  Match the beginning of the line\\
           \$ &  Match the end of the line (or before newline at the end)\\
           | &  Alternation\\
           () & Grouping\\
           $[ ]$ & Character class\\
	\end{tabular}
}

\frame
{
  	\frametitle{Tegnet . (punktum)}
	
	. (punktum) matcher et vilkårlig tegn.

	\begin{block}{Eksempel}
	\textbf{/bl.pp/} matcher ``blipp'', ``blapp'', ``blupp'' og så videre.
	\end{block}

	\begin{block}{NB:}
	``Vilkårlige tegn'' innebærer også whitespace, men per default ikke linjeskift (kan endres med en modifier vi snakker om senere).
	\end{block}
}

\frame
{
  	\frametitle{Tegnet * (stjerne)}
	
	* (stjerne) sier at forrige tegn skal matches 0 eller flere ganger.

	\begin{block}{Eksempel 1}
	\textbf{/bla*pp/} matcher ``blpp'', ``blapp'', ``blaapp'', ``blaaapp'' og så videre.
	\end{block}

	\begin{block}{Eksempel 2}
	\textbf{/bl.*pp/} matcher alt i Eksempel 1, samt f.eks. ``blupp'', ``blåbærkopp'', ``blå muggsopp'' og så videre.
	\end{block}
}

\frame
{
  	\frametitle{Tegnet + (pluss)}

	+ (pluss) fungerer akkurat som * (stjerne), bortsett fra at det er ``1 eller flere'' i stedet for ``0 eller flere''.

	\begin{block}{Eksempel}
	\textbf{/bla+pp/} matcher ``blapp'', ``blaapp'', ``blaaapp'' og så videre, men ikke ``blpp'' (som \textbf{/bla*pp/} ville matchet).
	\end{block}
}

\frame
{
  	\frametitle{Tegnet ? (spørsmålstegn)}
	
	? (spørsmålstegn) sier at forrige tegn skal matches ``0 eller 1'' ganger.

	\begin{block}{Eksempel}
	\textbf{/fisk?/} matcher ``fisk'' og ``fis'', og ingenting annet.
	\end{block}
}

\frame
{
  	\frametitle{Tegnene \{ og \} (krøllparenteser)}
	
	\{ og \} brukes for å gi et egendefinert intervall over hvor mange ganger forrige tegn skal matches.

	\begin{block}{Eksempler}
	\textbf{/fi\{3\}sk/} matcher ``fiiisk''.\newline
	\textbf{/fi\{2,3\}sk/} matcher ``fiisk'' og ``fiiisk''.\newline
	\textbf{/fi\{2,\}sk/} matcher ``fiisk'', ``fiiisk'', ``fiiiisk'' og så videre.
	\end{block}

	\begin{block}{NB!}
	Første argument er ikke valgfritt! \textbf{/fi\{,3\}sk/} matcher faktisk bare ``fi\{,3\}sk''.
	\end{block}
}

\frame
{
  	\frametitle{Sammenhengen mellom kvantifikatorene)}
	
	\begin{tabular}{|l|l|}\hline
	\textbf{Tegn} & \textbf{Krøllparentes-uttrykk} \\ \hline
	* & \{0,\} \\
	+ & \{1,\} \\
	? & \{0,1\} \\ \hline
	\end{tabular}

	Du kan med andre ord bruke kun \{ og \} om du vil, men ingen gjør det i praksis.
}

\frame
{
  	\frametitle{Tegnet \^{} og \$ (hatt og dollar)}

	\^{} og \$ matcher henholdsvis ``start of line'' og ``end of line''.

	Det vil altså si endene på variablene. Dersom det siste tegnet i variabelen
	er et linjeskift, matcher den også rett før linjeskiftet.

	\begin{block}{Eksempler}
	\textbf{/\^{}banan/} matcher ``banankompott'', men ikke ``stor banan''.\newline
	\textbf{/banan\$/} matcher ``stor banan'', men ikke ``banankompott''.\newline
	\textbf{/\^{}banan\$/} matcher kun ``banan'' eller ``banan$\backslash$n''.
	\end{block}
}

\frame
{
  	\frametitle{Tegnet | (pipe)}
	
	| (pipe) betyr ``eller'', og er sikkert velkjent fra boolsk algebra.
	Det kan settes mellom to eller flere alternativer for match.

	\begin{block}{Eksempel 1}
	\textbf{/banan|eple/} matcher både ``banan'' og ``eple'' (og strenger som inneholder en eller flere av dem av dem).
	\end{block}

	\begin{block}{Eksempel 2}
	\textbf{/banan|eple|pære/} matcher det samme som Eksempel 1, pluss ``pære''.
	\end{block}
}

\frame
{
  	\frametitle{Tegnene ``('' og ``)'' (parenteser)}
	
	Parenteser brukes til å gruppere, mye på samme måten som vi er vant til fra
	boolsk algebra.
	
	De brukes også til litt annet småtteri, som vi skal se på snart.

	\begin{block}{Eksempel}
	\textbf{/\^{}(banan|sviske)kompott\$/} matcher ``banankompott'' og ``sviskekompott''.
	\end{block}
}

\frame
{
  	\frametitle{Tegnene [ og ] (firkantparenteser)}
	
	Firkantparenteser brukes når det er flere alternativer til et tegn.
	Tegnene skrives rett og slett etter hverandre inni firkantparentesene.

	Firkantparenteser er egentlig et kapittel for seg, og kommer mer utfyllende senere.

	\begin{block}{Eksempel}
	\textbf{/bl$[$aui$]$pp/} matcher ``blapp'', ``blupp'' eller ``blipp''.
	\end{block}
}

\subsection{Mer om gruppering}

\frame
{
  	\frametitle{Mer om parenteser}
	
	Som vi så for ikke så lenge siden, brukes parenteser til å gruppere ting
	med. Vi så eksempelet \textbf{/\^{}(banan|sviske)kompott\$/}, der
	parenteser brukes til å avgrense skopet til variable.

	Parenteser kan imidlertid også brukes til å hente ut en substreng av det
	som ble matchet, og det kan vi bruke til mye rart.
}

\frame
{
  	\frametitle{Variablene \$1, \$2, \$3, etc. (1)}

	Når et uttrykk med parenteser i matcher, blir innholdet i parentesene lagt
	i spesielle variable, kalt ``tilbakereferanser''. Den første påbegynte
	parentesen blir lagt i \$1, den neste i \$2, og så videre.

	Merk at disse variablene må brukes med en gang, siden de forsvinner så fort
	du gjør en ny regex-matching lenger nede i koden. Ta en kopi!
}

\frame
{
  	\frametitle{Variablene \$1, \$2, \$3, etc. (2)}

	Dette eksempelet plasserer ``en'' i \$a og ``to'' i \$b dersom uttrykket
	matcher (og det gjør det).

	\begin{block}{Eksempel}
	my \$var = "en to";\newline
	my \$a;\newline
	my \$b;

	if (\$var =\~{} /(.*) (.*)/) \{\newline
	\hspace*{1em} \$a = \$1;\newline
	\hspace*{1em} \$b = \$2;\newline
	\}
	\end{block}

}

\frame
{
  	\frametitle{Direkte uthenting av tilbakereferanser}

	Om du kaller en matching i array-kontekst returneres alle
	tilbakereferansene som en array.

	Ulempen med denne metoden er at du må undersøke verdiene etterpå for å få
	vite om det matchet eller ikke, og det blir ikke like pent i mine øyne. 
	Notasjonen er heller ikke så intuitiv, spør du meg.

	Jeg ser sjelden denne konstruksjonen i bruk i praksis.

	\begin{block}{Eksempel}
	my \$var = "en to";\newline
	my (\$a, \$b) = \$var =\~{} /(.*) (.*)/;
	\end{block}
}

\frame
{
  	\frametitle{Bruk av tilbakereferanser i substitusjons-uttrykk}
	
	Du kan også bruke \$1 med venner i substitusjoner.

	\begin{block}{Eksempel}
	\# Dette bytter om på ``en'' og ``to''.\newline
	my \$var = ''en to'';\newline
	\$var =\~{} s/(.*) (.*)/\$2 \$1/;
	\end{block}

	\begin{block}{PS:}
	En del andre språk, som f.eks. sed og vim, bruker $\backslash$1 i stedet
	for \$1 og så videre.
	\end{block}
}

\frame
{
	\frametitle{Bruk av tilbakereferanser inne i selve patternet}

	Om du vil, kan du også bruke tilbakereferanser til en tidligere del av
	patternet lenger ute i regexen. Dette kan for eksempel være kjekt om du
	skal matche en serie av like tegn, men det er mer enn ett alternativ for
	hvilket tegn det er.

	Når du gjør tilbakereferanser inne i selve patternet, må du bruke
	$\backslash$1 i stedet for \$1 og så videre. \$1 og lignende vil
	\textit{ikke} virke! De er nemlig ikke definert ennå.

	\begin{block}{Eksempel: Fjerning av trippelkonsonanter}
	my \$var = ''busssjåfør'';\newline
	\$var =\~{} s/(.)$\backslash$1+/\$1\$1/g;
	\end{block}
}

\frame
{
  	\frametitle{Viktig bruksområde: Tainting}
	
	Tainted mode er en feature i Perl som tvinger deg til å sjekke inputen din
	til scripts. Det er et nyttig verktøy for å unngå lite kledelige
	sikkerhetshull i webapplikasjoner, for eksempel.

	Tainted mode virker slik at det eneste du får lov å bruke innleste (ergo
	potensielt skumle) variabler til, er å kjøre regex-matching på dem. Så kan
	du hente ut \$1 med venner derfra, og bruke dem.

	Tainted mode slås på med opsjonen -T bak perl-programmet.
}

\frame
{
  	\frametitle{Hvordan gruppere uten at innholdet huskes}
	
	Om du ønsker å bruke parenteser til gruppering, men \textit{ikke} ønsker å
	bruke innholdet i parentesen etterpå, kan du bruke ``?:'' først i
	parentesen.

	Dette er spesielt nyttig i split(), men også greit om du har masse
	parenteser du vil huske, men så plutselig noen du ikke vil huske midt inni.
	Det sparer også bittelitt minne, men det er mindre viktig.

	\begin{block}{Eksempel}
	\# returnerer (``b'', ``a'', ``n'', ``a'', ``n'', ``e'', ``r'')\newline
	my @a = split(/(a|e)/, "bananer");

	\# returnerer (``b'', ``n'', ``n'', ``r'')\newline
	my @b = split(/(?:a|e)/, "bananer");
	\end{block}
}

\subsection{Mer om tegnklasser}

\frame
{
  	\frametitle{Et gjensyn med $[$ og $]$}
	
	For en stund siden snakket vi så vidt om $[$ og $]$, som brukes for å
	definere en klasse av tegn. De skal vi snakke litt mer om nå.

	La oss først huske at en serie med tegn i firkantparenteser betyr at vi
	matcher ett av tegnene i firkantparentesen en gang.
	
	\begin{block}{Eksempel}
	\textbf{/$[$abc$]$/} matcher ett tegn, som kan være enten ``a'', ``b''
	eller ``c''. 
	\end{block}
}

\frame
{
  	\frametitle{Matching av fleksibelt antall tegn med tegnklasse}

	Skal vi matche et annet antall tegn enn nøyaktig ett, må vi (som vanlig)
	bruke en kvantifikator som f.eks. *, +, ? eller \{m,n\}.
	
	\begin{block}{Eksempel}
	\textbf{/$[$abc$]$+/} matcher ett eller flere tegn, som kan være enten
	``a'', ``b'' eller ``c''. 
	\end{block}
}

\frame
{
  	\frametitle{Tegnsekvenser}
	
	Siden det er litt tiltak å skrive tegnklasser som for eksempel
	\textbf{$[$0123456789$]$}, \textbf{$[$abcdef$]$} og sånt, har man mulighet
	for å angi intervaller. Dette gjøres med bindestrek.
	
	\begin{tabular}{|l|l|}\hline
	\textbf{Sekvens} & \textbf{Tilsvarer} \\ \hline
	\textbf{$[$0-9$]$} & \textbf{$[$0123456789$]$} \\ 
	\textbf{$[$a-f$]$} & \textbf{$[$abcdef$]$} \\ 
	\textbf{$[$0-9a-f$]$} & \textbf{$[$0123456789abcdef$]$} \\ 
	\hline
	\end{tabular}

	\begin{block}{Eksempel}
	\textbf{/\^{}0x$[$0-9a-fA-F$]$+\$/} matcher et hexadecimalt tall, som for
	eksempel ``0x1337babe''.
	\end{block}
}

\frame
{
  	\frametitle{Negasjon}
	
	Av og til ønsker du å matche alt unntatt visse tegn, som for eksempel alt
	unntatt kolon. For å gjøre dette kan du bruke en negert tegnklasse. Dette
	gjøres ved å sette tegnet \^{} (hatt) fremst i tegnklassen.

	Det stemmer, hatt betyr noe helt annet inni en tegnklasse enn den betyr
	utenfor. Litt forvirrende i starten, men det går fort over.

	\begin{block}{Eksempel}
	\textbf{/\^{}($[$\^{}:$]$*)/} matcher fra starten av strengen til første
	kolon (eller slutten av strengen, om det ikke finnes noe kolon i den) og
	legger resultatet i \$1.
	\end{block}
}

\frame
{
  	\frametitle{Escaping av spesielle tegn i tegnklasser}
	
	Siden \^{} (hatt), - (bindestrek) og $]$ har spesiell betydning i en
	tegnklasse ($]$ avslutter klassen), må man escape dem om man vil ha et
	bokstavelig tegn. 
	
	Dette kan gjøres enten ved å escape dem med backslash, eller ved å plassere
	dem spesielle steder i tegnklassen. I praksis brukes ofte spesiell
	plassering, siden dette er vanlig i andre regex-implementasjoner.

	\begin{tabular}{|l|l|} \hline
	\textbf{Tegn} & \textbf{Plassering for å escape} \\ \hline
	\^{} (hatt)    & Et annet sted enn fremst \\
	- (bindestrek) & Helt bakerst eller helt fremst (bak eventuell hatt) \\
	$]$            & Helt fremst (bak eventuell hatt) \\
	\hline
	\end{tabular}
}

\frame
{
  	\frametitle{Ferdigdefinerte tegnklasser}
	
	Perl har også en del ferdigdefinerte tegnklasser. Disse kan brukes enten som byggestener i egendefinerte tegnklasser, eller for seg selv.

	Eksemplene nedenfor benytter $\backslash$w, som matcher tegn som kan være i
	ord (det vil si bokstaver, tall og \_ (underscore)).

	\begin{block}{Eksempler}
	\textbf{/($\backslash$w+)/} henter ut det første ordet og legger det i \$1.

	\textbf{/($[$$\backslash$w-$]$+)/} gjør som forrige eksempel, men tillater
	bindestrek i ordet.
	\end{block}
}

\frame
{
  	\frametitle{Liste over ferdigdefinerte tegnklasser}

	Dette er en liten oversikt over de mest brukte ferdigdefinerte
	tegnklassene. Det finnes en del flere, men de er ikke like vanlige. Du
	finner dem i ``perldoc perlre''.
	
	\begin{tabular}{|l|l|}\hline
	\textbf{Klasse} & \textbf{betydning} \\ \hline
	$\backslash$w & Match a "word" character (alphanumeric plus ``\_'')\\
	$\backslash$W & Match a non-"word" character\\
	$\backslash$s & Match a whitespace character\\
	$\backslash$S & Match a non-whitespace character\\
	$\backslash$d & Match a digit character\\
	$\backslash$D & Match a non-digit character\\
	$\backslash$b & Match a word boundary\\
	\hline
	\end{tabular}
}

\section{Eksempler og avslutning}

\subsection{Eksempler}

\frame
{
  	\frametitle{Eksempel: Strippe HTML}
	
	Dette eksempelet har dere sikkert sett før, på plakaten til kurset. Nå har
	dere sikkert lært nok til å se hva den gjør også!

	Merk at om du leser inn en linje om gangen vil ikke denne koden støtte
	html-tags som går over flere linjer.

	Vi ser at uttrykket matcher en <, så innholdet i tagen (ett eller flere
	tegn som ikke er >, og så til slutt >. Substitusjonen er også global, så
	alle treffene blir erstattet med en tom streng.

	\begin{block}{Eksempel}
	\textbf{s/<$[$\^{}>$]$+>//g}
	\end{block}
}

\frame
{
  	\frametitle{Eksempel: Hente ut linker fra HTML}
	
	Om du vil hente ut alle linkene i et HTML-dokument, kan du for eksempel
	matche på det som er i hermetegn bak ``href=''.

	\textbf{$\backslash$s*} er med her og der fordi det er valgfritt med mellomrom der.

	\begin{block}{Eksempel}
	\textbf{/href$\backslash$s*=$\backslash$s*''([\^{}'']+)/i}
	\end{block}

	\begin{block}{I praktisk bruk}
	\textbf{perl -ne 'print ''\$1$\backslash$n'' if /href$\backslash$s*=$\backslash$s*''([\^{}'']+)/i' fil.html}
	\end{block}
}

\frame
{
  	\frametitle{Eksempel: Hente ut flere linker per linje fra HTML}
	
	Eksempelet på forrige slide hadde en begrensning: Det støttet bare en link
	per linje. Det er sikkert fullt mulig å lage en regex som støtter å fiske
	ut flere, og legge dem i \$1, \$2 og så videre, men det blir bare tungvint
	og ekkelt. I stedet kan vi enten modifisere input-dataene (f.eks. legge inn
	linjeskift mellom alle HTML-tags) eller kjøre flere matchinger per linje.
	Vi satser på å gjøre flere matchinger per linje.

	Her har vi samme regex som i stad, men substituerer bort patternet i stedet
	for å matche det. Slik holder vi på til det ikke er mer som matcher.

	\begin{block}{Eksempel}
	\textbf{perl -ne 'print ''\$1$\backslash$n'' while s/href$\backslash$s*=$\backslash$s*''([\^{}'']+)//i' fil.htm}
	\end{block}
}

\frame
{
  	\frametitle{Eksempel: Matche primtall}
	
	Følgende kode matcher et primtall. Den er vel kanskje ikke kjempe-intuitiv,
	men virker for små primtall. For store primtall går den kjapt tom for minne
	og tryner.

	Dette er for øvrig omtrent tregest tenkelige måte å regne ut om noe er
	primtall eller ikke, så den bør kun brukes som kuriositet ;-)

	Den fungerer ved at man først matcher to eller flere tegn, før man matcher
	denne sekvensen to eller flere ganger. I praksis bruteforcer man altså om
	tallet er delelig med noe.

	\begin{block}{Eksempel}
	perl -e '(1x\$ARGV$[$0$]$) =\~{} /\^{}(..+?)$\backslash$1+\$/ || print ``prime$\backslash$n'''
	\end{block}
}

\subsection{Avslutning}

\frame
{
	\frametitle{Generelle triks}

	Når du skriver en regex er det noen få triks som gjerne sparer deg for en
	del hodebry:

	\begin{itemize}
	\item Gjør den enkel først, legg på særtilfeller etter hvert.
	\item Test at den gjør det du vil underveis. Det er fort gjort å snike inn
		en skrivefeil som ødelegger alt.
	\item Om regexen blir kjempediger og fæl, stopp og tenk på hvorvidt dette
		egentlig var rett verktøy å bruke. Kanskje du bør lage en skikkelig
		parser i stedet?
	\item Av og til kan det være kjekt å først matche på et grovt pattern,
		hente ut det som er interessant, og så matche videre med en ny regex.
	\end{itemize}
}

\frame
{
  	\frametitle{Hva er Regex IKKE bra til?}
	
	Nå som vi har sett at regex gjør det mulig å gjøre masse flott, er det kanskje en plan å se litt på hva det \textit{ikke} passer så bra til.

	\begin{itemize}
	\item Regex støtter ikke rekursjon. Dette gjør det håpløst å matche f.eks.
		HTML skikkelig, siden vi ikke kan holde styr på start- og slutt-tager.
	\item Om teksten er litt komplisert er det ofte vel så greit å skrive en
		skikkelig parser, i stedet for en supergrisete regex.
	\item Regex er ikke veldig maintainable, spesielt ikke om du overdriver.
	\end{itemize}
}

\frame
{
  	\frametitle{Hvordan lære mer?}

	Om du vil lære mer, er det selvsagt et triks å bruke regex en del. Selv
	bruker jeg bortimot daglig regex til et eller annet, som regel i
	forbindelse med små onelinere jeg bruker for å massere tekst. Jeg bruker
	det også mye for å gjøre søk og erstatt i vim (jeg har brukt en del regexer
	i vim mens jeg skrev disse foilene).

	Om du vil lese mer, er kommandoen ``perldoc perlre'' veldig fin. O'Reilly
	har også noen bøker jeg tror er bra, og et par av dem ligger sikkert på
	PVV.

	Har man et obskurt problem er det også ofte hjelp å få på IRC, eventuelt på
	mailinglister med nerder på (som f.eks. aktive@pvv.ntnu.no).
}

\end{document}
