Merge commit 'origin'
[ailab3.git] / rapport.tex
blob7b88d0fe334e3789459f3caf9c9a753493fe885b
1 \documentclass[a4paper, 12pt]{article}
2 \usepackage[swedish]{babel}
3 \usepackage[utf8]{inputenc}
4 \usepackage{verbatim}
5 \usepackage{fancyhdr}
6 \usepackage{graphicx}
7 \usepackage{parskip}
8 % Include pdf with multiple pages ex \includepdf[pages=-, nup=2x2]{filename.pdf}
9 \usepackage[final]{pdfpages}
10 % Place figures where they should be
11 \usepackage{float}
13 % vars
14 \def\title{Projekt}
15 \def\preTitle{Laboration 3: Information Retrieval \& Extraction}
16 \def\kurs{Artificiell Intelligens med inriktning mot kognition och
17 design B, ht 2008}
19 \def\namn{Anton Johansson}
20 \def\mail{dit06ajn@cs.umu.se}
21 \def\namnett{Victor Zamanian}
22 \def\mailett{dit06vzy@cs.umu.se}
24 \def\handledareEtt{Dennis Olsson, denniso@cs.umu.se}
25 \def\inst{datavetenskap}
26 \def\dokumentTyp{Laborationsrapport}
28 \begin{document}
29 \begin{titlepage}
30 \thispagestyle{empty}
31 \begin{small}
32 \begin{tabular}{@{}p{\textwidth}@{}}
33 UMEÅ UNIVERSITET \hfill \today \\
34 Institutionen för \inst \\
35 \dokumentTyp \\
36 \end{tabular}
37 \end{small}
38 \vspace{10mm}
39 \begin{center}
40 \LARGE{\preTitle} \\
41 \huge{\textbf{\kurs}} \\
42 \vspace{10mm}
43 \LARGE{\title} \\
44 \vspace{15mm}
45 \begin{large}
46 \namn, \mail \\
47 \namnett, \mailett
48 \end{large}
49 \vfill
50 \large{\textbf{Handledare}}\\
51 \mbox{\large{\handledareEtt}}
52 \end{center}
53 \end{titlepage}
55 \newpage
56 \thispagestyle{empty}
57 \mbox{}
58 \newpage
60 \pagestyle{fancy}
61 \rhead{\footnotesize{\today}}
62 \lhead{\footnotesize{\namn, \mail \\ \namnett, \mailett}}
63 \chead{}
64 \lfoot{}
65 \cfoot{}
66 \rfoot{}
68 \section*{Sammanfattning}
69 Reguljära uttryck (Regular Expressions) är uttryck som innehåller
70 olika syntax för att identifiera specifika textsträngar ur en större
71 mängd text. Detta kan användas inom ämnet Artificiell Intelligens för
72 att till exempel validera och tolka indata och specificera olika typer
73 av språk.
75 \newpage
76 \tableofcontents
77 \newpage
79 \rfoot{\thepage}
80 \pagenumbering{arabic}
82 % TODO @anton - Problem-solving as search, basic to AI, Norvig.
84 \section{Introduktion}
85 % till ämnet.
86 Denna rapport går igenom användandet av Reguljära uttryck (Regular
87 Expressions på engelska, även förkortat som ''regexp'' eller bara
88 ''regex'') med avseende på informationshämtning inom området
89 Artificiell Intelligens.
91 Rapporten är formulerad och utförd enligt specifikation på sidan:\\
92 \begin{footnotesize}
93 \verb!http://www.cs.umu.se/kurser/5DV063/HT08/assignments/lab3-spes-ht08.html!
94 \end{footnotesize}
96 \section{Syfte}
97 % med uppgiften, beskrivet med egna ord.
98 Syftet med rapporten är att fördjupa sig inom ett smalt ämne inom
99 området Artificiell Intelligens och presentera teori för det valda
100 ämnet på ett vetenskapligt sätt.
102 \section{Metodbeskrivning}
103 %: beskrivning av metod, material, design och procedur
104 Denna rapport är sammanställd främst genom en litteraturstudie inom
105 området Artificiell Intelligens i förhållande till Reguljära uttryck.
106 Information och tankar är samlade från böcker och internetsidor, för
107 att försöka få en överblick över de Reguljära uttryckens betydelse och
108 användande inom området.
110 \section{Litteraturstudie}
111 %, teoretisk fördjupning
112 Enligt \cite{speech} härstammar Reguljära uttryck från Alan Turings
113 modell (1936) för aritmetisk beräkning, även kallad
114 Turingmaskin. Denna maskin var abstrakt, ett tankeexperiment, för att
115 utföra beräkningar.
116 % TODO Church-Turings hypotes säger att varje tänkbar process kan
117 % utföras av en Turingmaskin, och alltså finns det rent principiellt
118 % inte någon mer kraftfull beräkningsmekanism. Enligt wikipedia
119 % http://sv.wikipedia.org/wiki/Turingmaskin
121 Inspirerad av Turings arbete skapade sedan Warren McCulloch och Walter
122 Pitts (1943) en förenklad modell för neuronen, se \cite{norvig}
123 kapitel 18.
125 Stephen Cole Kleene definierade sedan (1951 och 1956) Ändlig
126 automation (Finite automation), Reguljära uttryck och påvisade deras
127 likhet.
129 Både Reguljära uttryck och Finite automation är en del av den språktyp
130 som brukar kallas Reguljära språk, (Regular Language).
132 I \cite{speech} ger man ett exempel på hur Finite automation och
133 Reguljära uttryck förhåller sig till varandra. Säg att man ska
134 definiera ett naturligt språk, för enkelhets skull försöker vi
135 definiera vad som är ''ko-språk''. Vi kan säga att korrekt
136 ''ko-språk'' definieras av kombinationerna:
138 \begin{verbatim}
139 Muu!
140 Muuu!
141 Muuuu!
143 \end{verbatim}
145 Detta skulle kunna beskrivas med en modell för \textbf{Finite-state
146 automation} enligt figur nedan.
148 \begin{figure}[H]
149 \begin{center}
150 \includegraphics[width=110mm]{images/state.pdf}
151 \caption{Ändlig automation för ''ko-språk''}
152 \label{state.pdf}
153 \end{center}
154 \end{figure}
156 Tillstånden \verb!q0-q4! är de giltiga tillstånd som finns, \verb!q1!
157 är starttillståndet och \verb!q4! representerar sluttillstånd. Pilarna
158 i figuren markerar möjliga förflyttningar mellan tillstånden.
160 Denna information går även att representera som en
161 \textbf{State-transition-tabell}, se nedan:
163 \begin{center}
164 \begin{tabular}{|c|l|l|l|}
165 \hline
166 & \multicolumn{3}{|c|}{Indata} \\
167 \hline
168 Tillstånd & M & u & ! \\
169 \hline
170 0 & 1 & 0 & 0 \\
171 1 & 0 & 2 & 0 \\
172 2 & 0 & 3 & 0 \\
173 3 & 0 & 3 & 4 \\
174 4 & 0 & 0 & 0 \\
175 \hline
176 \end{tabular}
177 \end{center}
179 Ovanstående tabell läses uppifrån och ner. Starttillståndet \verb!0!
180 har en giltig förflyttning till tillstånd \verb!1!, detta gäller
181 enbart för indata \verb!M!, för alla andra indata finns inga giltiga
182 förflyttningar, detta markeras med \verb!0!.
184 Det korresponderande \textbf{Reguljära uttrycket} för att beskriva
185 ''ko-språk'' skulle vara:
187 \begin{verbatim}
188 Muu+!
189 \end{verbatim}
191 Man läser det ungefär som man läser vanlig text. \verb!M! är tillåtet
192 starttillstånd, följt av ett \verb!u!, sedan markerar operatorn
193 \verb!u+! att en eller flera \verb!u! är tillåtna. Meningen avslutas
194 med \verb?!?, vilket markerar sluttillståndet. % Se sektion TODO för
195 mer info om regexp syntax.
197 % REGEXP-MANUAL:
198 % Står på sidan 848 i Norvig.
200 Ett reguljärt uttryck består enkelt nog av text som ska matchas. Om
201 man vill matcha texten ''hej'' i en textsträng ''hoppsanhejsan'' så
202 blir det reguljära uttrycket helt enkelt bara ''hej'' och ''hej'':et i
203 ''hoppsanhejsan'' matchas. Däremot är det mer sällan man använder
204 reguljära uttryck för sådana enkla matchningar. Man vill i stället
205 använda dem till att matcha \textbf{generella mönster}. Ett exempel på
206 ett mönster skulle kunna vara en e-postadress på formen
207 \verb!<användarnamn>@<subdomän>.<domän>!, där \verb!<användarnamn>!
208 kan innehålla (i detta exempel) alla siffror, alla små och stora
209 bokstäver (från A till Z), understreck, punkt, procenttecken,
210 bindestreck och plus.
212 I stället för att behöva skriva ett textmönster för varje e-postadress
213 som är möjlig att konstruera (i praktiken oräkneligt antal
214 variationer) kan man använda sig av speciella ''texthändelser'' för
215 att beskriva till exempel början\slash slutet av ett ord och
216 början\slash slutet av en hel sträng. Man kan också definiera
217 teckenklasser som man vill inkludera i sitt uttryck, till exempel alla
218 stora bokstäver, alla små bokstäver, siffror, eller till och med
219 vilken godtycklig kombination av tecken som helst. Här nedanför visas
220 en kort tabell med några texthändelser och deras motsvarande reguljära
221 uttryck.
223 \begin{center}
224 \begin{footnotesize}
225 \begin{tabular}{|c|p{4cm}|l|l|l|}
226 \hline
227 \textbf{regex-uttryck} & \textbf{Texthändelse} & \textbf{Exempel} & \textbf{Matchar} \\ \hline
229 \verb!\b! & Början eller slutet på ett ord & \verb!\b!text\verb!\b! & ''ord1 \textbf{text} ord3'' \\ \hline
231 \verb!^! & Början av en textsträng & \verb!^!text & ''\textbf{text} i början'' \\ \hline
233 \verb!$! & Slutet av en textsträng & \verb!lutet$! & ''text i s\textbf{lutet}'' \\ \hline
235 \verb![A-Za-z0-9]! & Definierar klass med tecknen A till Z, a
236 till z och 0 till 9. & \verb![abc0-9]! & ''\textbf{b}r\textbf{a} text med \textbf{23} te\textbf{c}ken'' \\
238 \hline
240 \verb!.! (punkt) & Står för vilket tecken som helst. & \verb!^.! & ''\textbf{t}ext'' \\ \hline
241 \end{tabular}
242 \end{footnotesize}
243 \end{center}
245 Om man vill matcha en e-postadress i löpande text skulle man alltså
246 vilja använda sig av \verb!\b! runt uttrycket för att markera att det
247 som finns runt omkring adressen måste vara ordavgränsare av något
248 slag, dvs. någon typ av blanktecken. Vill man däremot kontrollera
249 indata från till exempel ett formulärfält där det är meningen att en
250 användare ska ange enbart en e-postadress är det däremot önskvärt att
251 omsluta uttrycket med \verb!^! i början och \verb!$! i slutet för att
252 markera att hela strängen måste \textbf{börja och sluta med} adressen.
254 Låt oss definiera en teckenklass med alla siffror, dvs
255 ''\verb![0-9]!'' och använda det i ett reguljärt uttryck, till exempel
256 ''\verb!\b$[0-9]!''. Om vi sedan försöker matcha strängen ''\$10000''
257 med det mönstret kommer vi endast matcha följande (fet stil)
258 ''\textbf{\$1}0000''. Detta beror på att teckenklassen vi definierat
259 matchar bara \textit{det första} tecknet som platsar i
260 klassen. Självklart skulle vi vilja kunna matcha flera tecken i en och
261 samma teckenklass utan att behöva definiera en likadan klass för hela
262 det antalet tecken vi vill matcha. Därför har man definierat något som
263 kallas kvantifierare som gör att man kan bestämma hur många gånger man
264 vill matcha en specifik klass, ett mönster eller bara ett tecken (så
265 kallade ''tokens''). Nedanstående tabell beskriver olika
266 kvantifierare.
268 \begin{center}
269 \begin{footnotesize}
270 \begin{tabular}{|c|p{4cm}|l|p{4cm}|}
271 \hline
272 \textbf{kvantifierare} & \textbf{Beskrivning} & \textbf{Exempel} & \textbf{Matchar} \\ \hline
274 \verb!?! & Matchar föregående uttryck noll eller en gång. &
275 colou\verb!?!r & ''\textbf{colour}'' och ''\textbf{color}'' \\ \hline
277 \verb!+! & Matchar föregående uttryck en eller fler gånger. &
278 Mu\verb:+:! & ''\textbf{Mu!}'', ''\textbf{Muu!}'',
279 ''\textbf{Muuu!}'', \ldots \\ \hline
281 \verb!*! & Matchar föregående uttryck noll eller flera gånger &
282 10\verb!*! & ''\textbf{1}'', ''\textbf{10}'', ''\textbf{100}'',
283 \ldots \\ \hline
285 \verb!{!$n$\verb!,!$m$\verb!}! & Matchar föregående uttryck
286 minst $n$ gånger och som mest $m$ gånger. &
287 \verb!^!1\verb![!0\verb!]{!1,5\verb!}! & ''\textbf{10}'',
288 ''\textbf{100}'', ''\textbf{1000}'', ''\textbf{10000}'' och
289 ''\textbf{100000}'' men inte ''1'' och inte ''1000000'' (6
290 nollor eller mer).\\ \hline
291 \end{tabular}
292 \end{footnotesize}
293 \end{center}
295 Nu kan vi beskriva många olika variationer av mönster genom olika
296 texthändelser och kvantifierare, men vad händer om man vill inkludera
297 till exempel ett frågetecken i sitt mönster? Då måste man ''komma
298 runt'' (escape) frågetecknets regexp-betydelse för att komma åt dess
299 textuella värde. Detta görs vanligtvis med bakåtvänt snedstreck
300 (\textbackslash). Till exempel måste vi i vårt e-post\-adress\-mönster
301 matcha en punkt (i domännamnet), som vi måste uttrycka som
302 ''\verb!\.!''.
304 Nu har vi tillräckligt stor kunskap för att uttrycka ett reguljärt
305 uttryck som matchar en generell e-post\-adress. Vi börjar med att
306 beskriva \verb!<användarnamn>!. Användarnamnet kunde som sagt var
307 innehålla små och stora bokstäver (från A till Z), siffror, punkt,
308 understreck, procenttecken, plustecken och bindestreck. Vi uttrycker
309 detta som
311 \begin{verbatim}
312 \b[A-Za-z0-9._%+-]+
313 \end{verbatim}
315 där det sista plustecknet som sagt innebär att alla de tecken som den
316 definierade tecken\-klassen innefattar måste matchas minst en
317 gång. Plustecknet inom tecken\-klass\-definitionen tolkas som ett
318 ''textplus'' och inte som ett ''regex-plus''. Vi lägger också till
319 ordavgränsare som gör att uttrycket bara matchar användarnamnet i
320 början av ett nytt ord (dvs. själva e-post\-adressen) och inte matchar
321 ett användarnamn när det kommer direkt efter ett icke tillåtet
322 användarnamnstecken. Hade vi glömt ordavgränsaren hade följade
323 användarnamn matchats:
324 \\ ''\copyright\&\texttrademark\textexclamdown\textbf{sven.svensson}@host.doman''
325 vilket vi inte vill eftersom de icke tillåtna tecknen inte bör finnas
326 före användarnamnet.
328 Vi uttrycker sedan domännamnet som
330 \begin{verbatim}
331 [A-Za-z0-9.-]+\.[A-Za-z]{2,4}\b
332 \end{verbatim}
334 där plustecknet betyder precis samma sak som i uttrycket för
335 användarnamnet och ''\verb!\.!'' står för punktens textuella
336 värde. Sedan finns det ett krav på det som står efter punkten i
337 domännamnet, nämligen att denna ''token'' måste bestå av minst 2 och
338 som mest 4 tecken, därav kvantifieraren \verb!{!2\verb!,!4\verb!}!.
339 \verb!\b! i slutet av uttrycket innebär att det måste finnas en
340 ordavgränsare efter domännamnet.
342 Sätter vi nu samman dessa uttryck med ett snabel-a i mitten får vi ett
343 uttryck för en generell e-post\-adress \textbf{i löptext}. Vill vi
344 definiera ett uttryck för att undersöka om totala textmängden består
345 av endast en e-post\-adress kan vi ersätta \verb!\b! i början med
346 \verb!^! och i slutet med \verb!$! (till exempel om vi vill
347 kontrollera ett formulärfält på en webbsida)
348 \cite{regexinfo:website}. De två olika uttrycken ser ut som följer:
350 \begin{verbatim}
351 \b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\b
352 \end{verbatim}
356 \begin{verbatim}
357 ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$
358 \end{verbatim}
360 % Olika sätt att matcha e-mail adresser.
361 % \b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\b
362 % ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$
363 % http://www.regular-expressions.info/email.html
365 \section{Resultat}
366 % innehållande sammanställning/analys av eventuell testdata,
367 % implementering av algoritmer osv.
369 % TODO - resultat, användningsområden kopplade till AI.
370 % TODO @anton - Kolla upp och skriv om ELIZA, regexp memory.
371 \subsection{Applikationer av Reguljära uttryck}
372 Följande sektioner berör olika användningsområden för Reguljära
373 uttryck inom Artificiell intelligens.
375 \subsubsection{ELIZA}
376 Mer avancerade former av Reguljära uttryck kan använda sig av
377 minnesfunktioner för att spara tidigare matchningar. I
378 programmeringssråket Perl kan man göra ersättningar på formen:
379 \begin{verbatim}
380 s/hej/hejsan/
381 \end{verbatim}
383 Här ersätts alla \verb!hej! med \verb!hejsan!. För att spara träffar i
384 sökningen och ersätta med samma ord i ersättningssträngen använder man
385 grupper inom parenteser \verb!()!. Den sträng som en grupp matchar kan
386 sedan refereras till. \verb!\1!, till exempel, representerar
387 innehållet i första gruppen.
389 \begin{verbatim}
390 s/jag heter (\w+)/på dig \1, trevligt att höras/
391 \end{verbatim}
393 Ovanstående Reguljärt uttryck skulle ersätta ''Hej jag heter Anton''
394 med ''Hej på dig Anton, trevligt att höras''. Denna typ av Reguljära
395 ersättningar utgör grunden för implementationen av Chatroboten ELIZA,
396 som utvecklades av Joseph Weizenbaum, se \cite{speech}. Här följer en
397 kort konversation med Emacs implementering av ELIZA:
399 \begin{itemize}
400 \item[-] Hello my name is Anton
401 \item[-] \textbf{ELIZA:} How do you do? What brings you to see me?
402 \item[-] I need help with some Artificial Intelligence questions
403 \item[-] \textbf{ELIZA:} Why do you say you need help with some
404 artificial intelligence questions?
405 \item[-] I'm writing an essay about Regular Expressions
406 \item[-] \textbf{ELIZA:} Is it because of your plans that you say you
407 are writing an essay about regular expressions?
408 \item[-] yes
409 \item[-] \textbf{ELIZA:} I see... Well, what makes you believe this is so?
410 \end{itemize}
412 Ovanstående exempel vittar om att denna typ av chatrobot har en
413 relativt fast ram med frågor och svar att följa. Det tar inte lång tid
414 för en mänsklig användare att förstå att det inte är en mänsklig
415 motpart man kommunicerar med. ELIZA är implementerad för att svara på
416 frågor som rör psykoterapi--så fort man lämnar det bekanta ämnet blir
417 följdfrågorna ologiska ur ett mänskligt perspektiv.
419 Emacs implementation av ELIZA har en mängd hårdkodade svar. Följande
420 kodsnutt visar svaren som kan fås av indata som innehåller vissa
421 nyckelord gällade död:
423 \begin{footnotesize}
424 \begin{verbatim}
425 (setq deathlst
426 '((this is not a healthy way of thinking \.)
427 ((doc$ bother) you\, too\, may die someday \?)
428 (i am worried by your obsession with this topic!)
429 (did you watch a lot of crime and violence on television as a child \?))
431 \end{verbatim}
432 \end{footnotesize}
434 Även mängder med vanliga ord sparas för att på ett bättre sätt kunna
435 tolka indata, exempelvis vanliga synonymer, pronomen, verb och förkortningar:
437 \begin{footnotesize}
438 \begin{verbatim}
439 (setq replist
440 (wanna . (want to))
441 (gimme . (give me))
442 (gotta . (have to))
443 (gonna . (going to))
444 (never . (not ever))
445 ...)
446 \end{verbatim}
447 \end{footnotesize}
449 \subsubsection{Tolkning av indata}
450 Det finns en mängd användbara Reguljära uttryck för att tolka och på
451 ett vettigt sätt behandla indata som ett datorsystem får från
452 användare. Det kan gälla exempelvis verifiering av e-postadresser,
453 datum, person- och telefonnummer och så vidare. Detta är användbart
454 vid all typ av indata från användare, och i hög grad aktuellt när det
455 gäller forumlär på Internet.
457 Till exempel kan man istället för att kräva att användare ska skriva
458 för- och efternamn i separata rutor använda Reguljära uttryck för att
459 försöka tolka vad som är vad. Samma sak gäller adresser och
460 telefonnummer. Det kan vara intressant att ha information och ett
461 telefonnummers riktnummer och landskod, utan att för den sakens skull
462 kräva att en användare ska behöva specificera allt sådant manuellt.
463 Följer man bara vanliga konventioner för hur telefonnummer skrivs kan
464 man skapa ett Reguljärt uttryck för att fånga upp all denna
465 information ur en enda textsträng. All sådan här tolkning av indata är
466 väldigt bra ur användarsynpunkt, ''Don't make me click'', som Aza
467 Raskin \cite{raskin:website} säger i en presentation om
468 användarvänlighet på webbsidor.
470 %@TODO fixa url löpande
471 Ett annat bra exempel på hur Reguljära uttryck kan underlätta
472 inmatning av data finns implementerat i den webbaserade
473 kalendertjänsten från Google Inc. (\begin{footnotesize}
474 http://google.com/calendar/\end{footnotesize}). För att skapa en ny
475 händelse i kalendern kan användaren klicka på aktuell dag och skriva
476 till exempel ''Äta mat hos mamma kl 10-12''. Detta genererar en
477 händelse med rubrik ''Äta mat hos mamma'' och placeras med start kl 10
478 och slut kl 12 i kalendern. Ett Reguljärt uttryck för detta skulle
479 kunna vara att matcha de första siffrorna efter \verb!(kl|klockan)!,
480 dessa borde vara starttimme för händelsen. Följs dessa siffror av
481 \verb!.! eller \verb!:! utan mellanslag efter skulle nästa två siffror
482 kunna representera minuter, nästa siffror, eventuellt efter ett
483 bindestreck, kan representera sluttid. På detta sätt kan man med hjälp
484 av Reguljära uttryck representera naturligt språk för datorn. Vidare
485 skulle extra nyckelord kunna läggas in, till exempel \verb!hos!,
486 \verb!på! eller \verb!i! för att markera att det som följer är en
487 plats, eller \verb!med! för att markera att följande text innehåller
488 information om deltagare i händelsen.
490 \subsubsection{Datahämtning}
491 Reguljära uttryck kan användas för att hämta och tolka information ur
492 en större mängd data. Ett trivialt exempel är till exempel att försöka
493 svara på frågan, ''Vad är det för väder i Umeå idag?'' baserat på
494 innehållet från sidan:
496 \begin{verbatim}
497 http://www.tfe.umu.se/weather/1440/900/10/sv-SE/now.htm
498 \end{verbatim}
500 Html-taggen som visar den aktuella temperaturen i Umeå har följande
501 utseende:
502 \begin{verbatim}
503 <td class="tempfont" ... >0,7 &deg;C</td>
504 \end{verbatim}
506 Det som skiljer denna tagg från de andra på sidan är attributet
507 \verb!class="tempfont"!. Den aktuella temperaturen visas mellan
508 \verb!<td ...>! och \verb!</td>!, det innebär att det i detta exempel
509 skulle vara $0,7\,^{\circ}\mathrm{C}$ dagen sidan hämtades. Följande
510 Reguljära uttryck matchar den strängen som innehåller temperatur i sin
511 första grupp, dvs uttrycket inom \verb!()!, som senare kan refereras
512 till med \verb!\1!:
514 \begin{verbatim}
515 <td class="tempfont.+?>([0-9]+,[0-9]+)
516 \end{verbatim}
518 Med denna information kan man sedan förenkla och säga att bra väder
519 gäller för alla $temperaturer \geq 15$ och dåligt väder gäller för
520 $temperaturer < 15$. Detta Reguljära uttryck är mycket specifikt och
521 enbart användbart på denna specifika sida så länge temperaturen
522 inkapslas exakt av den HTML-taggen och eventuella attribut.
524 \section{Diskussion}
525 % av resultatet, koppling till tidigare studier.
527 \section{Slutsats}
530 %. Använd minst två referenser utöver kursboken.
531 \bibliographystyle{alpha}
532 \bibliography{books}
534 \end{document}