lehrkraefte:blc:informatik:efi-2023:regex

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
lehrkraefte:blc:informatik:efi-2023:regex [2023/12/05 07:15] Ivo Blöchligerlehrkraefte:blc:informatik:efi-2023:regex [2023/12/14 08:25] (current) – [Ausprobieren] Ivo Blöchliger
Line 1: Line 1:
 +====== Regular Expressions ======
 +Beschreibung von Text-Mustern. Zum Suchen, Extrahieren und Ersetzen von Text.
 +Gibt es in (fast) allen Programmiersprachen und jedem besseren Text-Editor (z.B. Notepad++, VisualCode, vim, etc.)
 +
 +Je nach Implementation gibt es kleine Unterschiede zwischen Programmiersprachen oder Text-Editoren.
 +
 +===== Wichtigste Spezialzeichen =====
 +Wenn nicht speziell, steht ein Zeichen für sich selbst in einer regular Expression. Z.B. matcht /hallo/ nur genau "hallo"
 +
 +  * ''.'' steht für genau ein beliebiges Zeichen (ausser Zeilenumbruch)
 +  * ''\.'' steht für einen Punkt
 +  * ''[abc246]'' steht für genau ein beliebiges Zeichen in der Klammer
 +  * ''[5-9e-k]'' steht für genau ein Zeichen '5' bis '9' oder 'e' bis 'k'
 +  * ''\d'' Digit, Abkürzung für ''[0-9]''.
 +  * ''\['' steht für die öffnende Klammer
 +  * ''^'' Start der Zeile (oder String)
 +  * ''$'' Ende der Zeile (oder String)
 +
 +Quantoren:
 +  * ''*'' beliebig viele der Expression davor (auch Null), **greedy**, d.h. match't so viel wie irgend möglich
 +  * ''+'' ein oder mehrere der Expression davor, **greedy**
 +  * ''?'' Null oder eins, **greedy**
 +  * ''{7}'' genau 7
 +  * ''{4,7}'' zwischen 4 und 7, **greedy**
 +  * ''*?'' beliebig viele, aber **lazy** (d.h. match't so wenig wie möglich). Ebenso ''??'', ''+?'' und ''{4,7}?''.
 +
 +Gruppen:
 +  * ''(''expr'')'' «speichert» den Match zur späteren Verwendung mit ''\1'' oder ''$1'', je nach Engine. Es wird nach öffnender Klammer nummeriert.
 +
 +Alternativen:
 +  * ''|'' Die Expression davor, oder jene danach.
 +
 +
 +===== Ausprobieren =====
 +  * https://regex101.com/ Verwenden Sie Python. Die Dokumentation von Python RegEx: https://docs.python.org/3/library/re.html
 +
 +  * http://regextutorials.com/
 +  * https://regexcrossword.com/
 +  * https://alf.nu/RegexGolf  (Yay!)
 +  * https://regexone.com/
 +  * https://regex.sketchengine.eu/basic-exercises.html
 +==== Aufgabe: Links extrahieren ====
 +  * Extrahieren Sie alle Links von folgendem Code-Schnipsel:
 +<code txt>
 +<a href='./68ac1106/spaceadventure.html'>./68ac1106/spaceadventure.html</a><br>
 +<a href='./0475c543/mouseEffect.html'>./0475c543/mouseEffect.html</a><br>
 +<a href='./76163dbd/Taschenrechner.html'>./76163dbd/Taschenrechner.html</a><br>
 +<a href='./4b29d86a/index.html'>./4b29d86a/index.html</a><br>
 +<a href='./05c7c22f/wordle.html'>./05c7c22f/wordle.html</a><br>
 +<a href='./4d4f79fa/index.html'>./4d4f79fa/index.html</a><br>
 +<a href='./2750fa3e/index.html'>./2750fa3e/index.html</a><br>
 +<a href='./projects.html'>./projects.html</a><br>
 +</code>
 +  * Vervollständigen Sie obige Links mit der vollständigen Adresse: https://ofi.tech-lab.ch/2022/EF05a/ 
 +  * Im angezeigten Text soll die Pfadangabe und das .html verschwinden (also nur noch wordle anstatt ./05c7c22f/wordle.html)
 +
 +
 +<hidden Lösungsvorschläge>
 +<code txt>
 +search for 
 +'(.*?)'
 +
 +search for 
 +'.\/(.*?)'
 +replace by 
 +'https://ofi.tech-lab.ch/2022/EF05a/$1'
 +
 +search for 
 +>\.\/.*?\/(.*?)\.html<
 +replace by
 +>$1<
 +</code>
 +</hidden>
 +
 +==== Realworld-Aufgabe: Christbaum-Logdaten analysieren ====
 +Kopieren Sie die log-Datei vom Christbaum und analysieren Sie diese.
 +<code bash>
 +scp ef:python/logs/xmaslights-2023-11-30T164809.401678.log .
 +</code>
 +Mögliche Fragen:
 +  * Welches Programm wurde besonders oft ausgewählt?
 +  * Um welche Uhrzeiten hat der Bewegungsmelder etwas wahrgenommen? Plotten Sie das auch schön.
 +
 +
 +<code python>
 +import re
 +
 +fn = "xmaslights-2023-11-30T164809.401678.log"
 +
 +with open(fn, "r") as f:
 +    lines = f.readlines()
 +
 +pattern = re.compile("since motion: (\d+\.\d+)")
 +#pattern = re.compile("text=")
 +
 +for line in lines:
 +    res = pattern.search(line)
 +    if res:
 +        #print(line)
 +        print(res.group(1))
 +</code>
 +==== Realworld-Aufgabe: Daten aus einer Nesa-Seite extrahieren ====
 +Hier finden Sie einen Screenshot und den zughörigen HTML-Code: {{lehrkraefte:blc:informatik:efi-2023:raumplanh21.zip}}.
 +
 +Schreiben Sie ein Python-Programm mit regular Expressions, das den Raumplan extrahiert.
 +
 +=== Warum das Blödsinn ist ===
 +Gegen eine UI zu programmieren, ist ok für den Einmalgebrauch. Es ist aber nicht nachhaltig, weil die UI jederzeit ändern kann (und wird!). 
 +
 +Auch haben wir HTML-Code vorliegen. Dieser ist bereits strukturiert und auch danach durchsuchbar. Z.B. kann man die Sache in JavaScript «relativ» einfach erledigen (In den Entwickler Tools des Webbrowsers (F12)):
 +<code javascript>
 +Array.from(document.querySelectorAll('.stpt_event_body')).map(e=>e.getAttribute('title'))
 +</code>
 +Liefert ein Array mit den gewünschten Einträgen.
 +
 +
 +
 +==== Weitere Übungen ====
 +Mit einem [[https://fginfo.ksbg.ch/dokuwiki/doku.php?id=lehrkraefte:blc:informatik:ffprg1-2022:wordle:start#wortliste|Crawler in Python]] habe ich deutsche Wortlisten erstellt: {{kurse:ef05a-2021:wortliste05.txt}}.
 +
 +Diese Wortliste soll z.B. für ein Wordle-Spiel gebraucht werden. Dazu sind allerdings noch einige Aufräumarbeiten nötig:
 +  * Extrahieren Sie erst die Zeilen, deren Wörter mindestens 100 mal gefunden wurden.
 +    * Hinweis: Das könnte auch auf der Kommandozeile mittels ''grep -e'' //regexp// ''wortliste05.txt'' geschehen.
 +  * Entfernen Sie alle Zahlen (und den Leerschlag)
 +    * Hinweis: das könnte auch auf der Kommandozeile mittels ''cut -f1 -d" "'' erreicht werden.
 +Dann wollen wir mal «spezielle» Wörter suchen:
 +  * Suchen Sie alle Wörter, die einen Doppelbuchstaben (zwei gleich hintereinander) haben.
 +  * Suchen Sie alle Wörter, in denen ein Buchstabe zwei mal vorkommt.
 +  * Suchen Sie alle Wörter, in denen ein Buchstabe drei mal vorkommt.
 +
 +
 +Auf https://sourceforge.net/projects/germandict/ gibt es eine Wortliste mit 1.2 Millionen Wörten, die in deutschen Texten vorkommen können. Extrahieren Sie daraus:
 +  * Evtl. ß durch ss ersetzen.
 +  * Evtl. ä, ö, ü durch ae, oe, ue ersetzen.
 +  * Wörter die aus genau 5 Buchstaben A-Z und a-z bestehen
 +  * Nur der erste Buchstaben darf gross sein, alle anderen müssen klein sein.
 +  * Das Wort muss mindestens einen Vokal enthalten.
 +  * Liste sortieren, doppelte Wörter entfernen.
 +  * Danach bleiben {{kurse:ef05a-2021:huge5.txt|6308 Wörter.}}
 +
 +<hidden Lösungsvorschlag auf der Kommmandozeile>
 +<code bash>
 +cat utf8.txt | sed -e s/ß/ss/g | sed -e s/ä/ae/g | sed -e s/ö/oe/g | sed -e s/ü/ue/g | grep -E '^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvxzy][abcdefghijklmnopqrstuvxzy]{4}$' | grep -E '[AEIOUaeiou]' | tr 'a-z' 'A-Z' | sort | uniq | wc
 +</code>
 +</hidden>
 +
 +==== Wordle-Pro mit regular Expressions ====
 +Aus den 6308 Wörtern, was ist die Lösung zu folgenden Wordle-Rätseln?
 +
 +{{:kurse:ef05a-2021:pasted:20220509-101601.png}}
 +<code txt>
 +[^OENICHKAGL\n]{3}LT
 +</code>
 +<HTML><hr></HTML>
 +{{:kurse:ef05a-2021:pasted:20220509-101840.png}}
 +
 +
 +Hinweis: N muss an erster oder vierter Stelle stehen. Mit dem Pipe Zeichen ''|'' können mehrere Expressions durch ''oder'' verknüpft werden.
 +<code txt>
 +^NRA[^BOTULKGZA]S|^[^BOTULKGZA]RANS
 +</code>
 +<HTML><hr></HTML>
 +{{:kurse:ef05a-2021:pasted:20220509-102029.png}}
 +<code txt>
 +^S[^INDZGERPT]O[^INDZGERPT]{2}
 +</code>
 +<HTML><hr></HTML>
 +{{:kurse:ef05a-2021:pasted:20220509-102145.png}}
 +
 +<code txt>
 +^NE[^KATJOLSHR]R[^KATJOLSHRN]|^[^KATJOLSHR]ENR[^KATJOLSHRN]
 +</code>
 +==== Alternativen für HTML, JSON, XML und allg. maschinenlesabare Formate ====
 +Um Daten aus HTML, JSON oder XML nachhaltig zu extrahieren/manipulieren, ist es ratsam, Werkzeuge zu verwenden, die das entsprechende Format verstehen, z.B. für
 +  * HTML: direkt mit JavaScript und z.B. [[https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector|document.querySelector]] arbeiten.
 +  * JSON: Daten parsen (in irgendeiner Programmiersprache) und direkt dort manipulieren.
 +  * XML: dafür gibt es ebenfalls Parser
 +Das Problem mit «selbstgestrickten» regular Expressions ist, dass diese halt schnell an ihre Grenzen stossen und zu wenige oder zu viele Resultate liefern.
 +
 +===== Weiterführende Links =====
 +  * Advanced stuff: http://rexegg.com/regex-best-trick.html
 +