# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# + [markdown] slideshow={"slide_type": "slide"}
# ## Reguläre Ausdrücke
#
#

# + [markdown] slideshow={"slide_type": "subslide"}
# ### Eingangsbeispiel -  Standardisierung von Straßennamen

# + slideshow={"slide_type": "subslide"}
string = '100 NORTH MAIN ROAD'
string.replace("ROAD", "RD.")

# + slideshow={"slide_type": "subslide"}
string = '100 NORTH BROAD ROAD' # problem
string.replace("ROAD", "RD.")

# + slideshow={"slide_type": "subslide"}
string[:-4] + string[-4:].replace('ROAD', 'RD.') # umstaendliche und spezifische loesung

# + slideshow={"slide_type": "subslide"}
import re
re.sub('ROAD$', 'RD.', string) # regulaerer ausdruck

# + [markdown] slideshow={"slide_type": "subslide"}
# [Reguläre Ausdrücke](https://de.wikipedia.org/wiki/Regul%C3%A4rer_Ausdruck) (regular expressions) spezifizieren Mengen von Zeichenketten, die über verschiedene Operationen identifiziert werden können. Für Data Scraping sind reguläre Ausdrücke sehr hilfreich um z.B. relevante Texte aus Webseiten PDF's zu extrahieren.
#
# > Some people, when confronted with a problem, think “I know, I'll use regular expressions.” Now they have two problems.
#
# > *<NAME>* 	 

# + [markdown] slideshow={"slide_type": "subslide"}
# ### `re`
#
# Das Paket [re](https://docs.python.org/3/library/re.html) für reguläre Ausdrücke ist in der Standardbibliothek von Python enthalten.
#

# + slideshow={"slide_type": "subslide"}
import re

pattern = 'a'
string = 'Spam, Eggs and Bacon'

# + slideshow={"slide_type": "subslide"}
print(re.match(pattern, string)) # Sucht am Anfang des Strings

# + slideshow={"slide_type": "subslide"}
print(re.search(pattern, string)) # Sucht erstes Auftreten im String

# + [markdown] slideshow={"slide_type": "subslide"}
# Als Objekt:

# + slideshow={"slide_type": "fragment"}
pattern = re.compile('a')

print(pattern.search(string)) # nur suchen

# + slideshow={"slide_type": "fragment"}
print(pattern.search(string).group()) # suchen und ausgeben ueber group

# + [markdown] slideshow={"slide_type": "subslide"}
# ### `re.findall`
# Findet alle Vorkommnisse in einem String und gibt diese als *Liste-von-Strings* zurück.

# + slideshow={"slide_type": "fragment"}
print(string)

# + slideshow={"slide_type": "fragment"}
print(re.findall('a', string))

# + slideshow={"slide_type": "fragment"}
print(re.findall(' ', string))

# + [markdown] slideshow={"slide_type": "subslide"}
# ### Sonderzeichen:
#
# 1. `.` (dot) ist der allgemeinste, reguläre Ausdruck. Er spezifiziert ein beliebiges Zeichen im String.
# 2. `^` (carret) bezeichnet den Anfang eines Strings.
# 3. `$` (dollar) bezeichnet die Position vor der newline (`\n`) oder das Ende des Strings im `MULTILINE` Modus.

# + slideshow={"slide_type": "subslide"}
print(string)

# + slideshow={"slide_type": "subslide"}
print(re.search('.a.', string).group()) # erster treffer

# + slideshow={"slide_type": "subslide"}
print(re.findall('.a.', string)) # alle treffer

# + [markdown] slideshow={"slide_type": "subslide"}
# ### Verkettung
#
# Spezifiziert Strings in bestimmter Reihenfolge. Die Reihenfolge kann negiert werden in dem man eine Menge angibt: `[]`.

# + slideshow={"slide_type": "fragment"}
print(re.search('AND', 'AND DNA XYZ').group())

# + slideshow={"slide_type": "fragment"}
print(re.findall('[AND]', 'AND DNA XYZ'))

# + slideshow={"slide_type": "fragment"}
print(string)
print(re.findall('[amb]', string))

# + [markdown] slideshow={"slide_type": "subslide"}
# ### Alternative
#
# Findet mehrere Alternativen regulärer Ausdrücke. Wird durch `|`-Operator angegeben.

# + slideshow={"slide_type": "fragment"}
print(re.findall('AND|DNA|RNA', 'AND DNA XYZ')) 

# + [markdown] slideshow={"slide_type": "subslide"}
# ### Weitere Sonderzeichen
# Folgende Zeichen haben besondere Bedeutungen in regulären Ausdrücken:
#
# Zeichen | Bedeutung
# -|-
# `.`| Beliebiges Zeichen. Mit `DOTALL` auch die Newline (`\n`)
# `^`| Anfang eines Strings. Wenn `MULTILINE`, dann auch nach jedem `\n`
# `$`| Ende des Strings. Wenn `MULTILINE`, dann auch vor jedem `\n`
# `\`| Escape für Sonderzeichen oder bezeichnet eine Menge
# `[]`| Definiert eine Menge von Zeichen
# `()`| Festlegung von Gruppen  

# + [markdown] slideshow={"slide_type": "subslide"}
# ### Wiederholungen
# Spezifiziert Anzahl der Wiederholungen des vorangegangenen regulären Ausdrucks. Folgende Wiederholungen sind möglich:
#
# Syntax | Bedeutung
# -|-
# `*` | 0 oder mehr Wiederholungen
# `+` | 1 oder mehr Wiederholungen
# `{m}` | Genau `m` Wiederholungen
# `{m,n}` | Von `m` bis einschließlich `n`
#

# + slideshow={"slide_type": "subslide"}
peter = '''The screen is filled by the face of PETER PARKER, a 17 year 
old boy. High school must not be any fun for Petttter, he's one 
hundred percent nerd- skinny, zitty, glasses. His face is just 
frozen there, a cringing expression on it, which strikes us odd 
until we realize the image is freeze framed.'''


# + slideshow={"slide_type": "subslide"}
peter

# + [markdown] slideshow={"slide_type": "subslide"}
#
# Die Wiederholungen sind standardmäßig *greedy*, d.h. es wird soviel vom String verbraucht, wie möglich. Dieses Verhalten kann abgeschaltet werden, indem ein `?` nach der Wiederholung gesetzt wird.

# + slideshow={"slide_type": "subslide"}
print(re.findall('s.*n', peter)) # greedy

# + slideshow={"slide_type": "subslide"}
print(re.findall('s.*?n', peter)) # non-greedy

# + [markdown] slideshow={"slide_type": "subslide"}
# Zusatzparameter `re.DOTALL` um über `.` auch `\n` zu erfassen:

# + slideshow={"slide_type": "subslide"}
print(re.findall('s.*?n', peter, re.DOTALL))

# + slideshow={"slide_type": "subslide"}
re.findall('\.', peter) # suche nach punkt, escapen des sonderzeichens "."

# + [markdown] slideshow={"slide_type": "subslide"}
# Grundsätzlich kann die Regex Kombination, `.*?`, verwendet werden, um mehrere Platzhalter (`.`) beliebig häufig (`*`) vorkommen zu lassen, solange bis das nächste Pattern zum ersten mal gefunden wird (`?`).

# + slideshow={"slide_type": "fragment"}
string = 'eeeAaZyyyyyyPeeAAeeeZeeeeyy'
print(re.findall('A.*Z', string)) # greedy

# + slideshow={"slide_type": "fragment"}
print(re.findall('A.*?Z', string)) # non-greedy

# + [markdown] slideshow={"slide_type": "subslide"}
# ### Spezifizierung von Mengen
#
# Syntax | Äquivalent | Bedeutung
# -|-|-
# `\d` | `[0-9]` | Ganze Zahlen
# `\D` | `[^0-9]` | Alles was keine Zahl ist
# `\s` | `[ \t\n\r\f\v]` | Alles was whitespace ist 
# `\S` | `[^ \t\n\r\f\v] ` | Alles was nicht whitespace ist
# `\w` | `[a-zA-Z0-9_]` | Alphanumerische Zeichen und Unterstrich
# `\W` | `[^a-zA-Z0-9_]` | Kein alphanumerische Zeichen oder Unterstrich

# + slideshow={"slide_type": "subslide"}
print(peter)

# + slideshow={"slide_type": "subslide"}
re.sub('\s', '_', peter) # ersetzen

# + slideshow={"slide_type": "subslide"}
re.findall('\d', peter) # alle zahlen

# + slideshow={"slide_type": "fragment"}
re.findall('\d{2}', peter) # zwei aufeinanderfolgende zahlen

# + [markdown] slideshow={"slide_type": "subslide"}
# ### Look arounds
#
# Look arounds ermöglichen es Mengen vor und nach Strings zu prüfen ohne diese zu extrahieren. Grundlegende Syntax: `(?`...`)`
#
# Syntax | Bedeutung
# -|-
# `(?=`...`)` | *positive lookahead*
# `(?!`...`)` | *negative lookahead*
# `(?<=`...`)` | *positive lookbehind*
# `(?<!`...`)` | *negative lookbehind*

# + slideshow={"slide_type": "subslide"}
string = 'bacon, eggs & spam'
re.findall('(?<=eggs).*', string) # positive lookbehind: alle zeichen nach "eggs"

# + slideshow={"slide_type": "subslide"}
string = "1pt 7px 3em 4px"
re.findall("\d+(?!px)", string) # negative look ahead: zahlen die nicht vor "px" stehen

# + [markdown] slideshow={"slide_type": "subslide"}
# Weitere Tutorials und  Infos zu regulären Ausdrücken:
#
# [DiveIntoPython Tutorial](https://diveintopython3.net/regular-expressions.html)
#
# [PyDocs RegEx HowTo](https://docs.python.org/3/howto/regex.html)
#

# + [markdown] slideshow={"slide_type": "subslide"}
# ### Übungsaufgabe 1
#
# Schreibt einen regulären Ausdruck, über den alle Wörter aus einem String in eine Liste überführt werden.

# + slideshow={"slide_type": "fragment"}
beispiel_string = '''The screen is filled by the face of <NAME>, a 17 year 
old boy. High school must not be any fun for Petttter, he's one 
hundred percent nerd- skinny, zitty, glasses. His face is just 
frozen there, a cringing expression on it, which strikes us odd 
until we realize the image is freeze framed.'''

# Code Übungsaufgabe 1


# + [markdown] slideshow={"slide_type": "subslide"}
# ### Übungsaufgabe 2
#
# Nutzt reguläre Ausdrücke um eine Liste von URL's nach Bildern (.jpg, .jpeg, .png) zu filtern.

# + slideshow={"slide_type": "subslide"}
beispiel_links = [
'https://www.uni-bamberg.de/ma-politik/schwerpunkte/computational-social-sciences/',
'https://www.uni-bamberg.de/fileadmin/_processed_/f/c/csm_Schmid_Finzel_2c34cb23de.jpg',
'https://www.uni-bamberg.de/fileadmin/uni/verwaltung/presse/042_MARKETING/0421_Corporate_Design/Logos-extern/weltoffene-hochschule/Logo-EN-170.png',
'https://www.uni-bamberg.de/fileadmin/_processed_/e/d/csm_2020-04-30_Homeschooling_web_4cf4ce1ad8.jpeg',   
'https://www.uni-bamberg.de/soziologie/lehrstuehle-und-professuren/']

# Code Übungsaufgabe 2


# + [markdown] slideshow={"slide_type": "subslide"}
# <br>
# <br>
#
#
# ___
#
#                 
# **Kontakt: <NAME>** (Webseite: www.carstenschwemmer.com,  Email: <EMAIL>)

StarcoderdataJupyterScriptsDedupFiltered