regex#

Ausprobier-Notebook zu 14: String Manipulation and Regular Expressions > flexible-pattern-matching-with-regular-expressions

Achtung: Hier geht es darum, wie man eine Regex in Python verwendet, die man schon konstruiert hat. Die Regex selbst wird man nicht hier im Quellcode konstruieren (geht nur für Experten) und testen (geht auch für Experten nicht), sondern z.B. unter https://regex101.com/

Vorbemerkung:

Achtung, nicht verwechseln: Der Kleene-Strern in der bash bedeutet “Null oder mehr Zeichen”

!ls *AUTO*.ipynb
e_r1_quizz_AUTO.ipynb			     f_f7_AUTO.ipynb
e_r2b_AUTO.ipynb			     f_f8_2024-03-03_AUTO.ipynb
e_r2_funktionsparameter_BMI_AUTO.ipynb	     json-beispiel42_AUTO.ipynb
f_f1_AUTO.ipynb				     q_r2b_AUTO.ipynb
f_f2_AUTO.ipynb				     quizz_mc_typen_AUTO.ipynb
f_f3_bibliotheken-kernfunktionen_AUTO.ipynb  zweimalzwei_AUTO.ipynb
f_f4_AUTO.ipynb				     zweiundvierzig_AUTO.ipynb
f_f5_AUTO.ipynb

in RegEx bedeutet der Kleene-Stern:

  • null mal oder öfters das vorausgehende Teilpattern

Bibliothek importieren:

import re
leerzeichen = re.compile('\s+')
<>:1: SyntaxWarning: invalid escape sequence '\s'
<>:1: SyntaxWarning: invalid escape sequence '\s'
/tmp/ipykernel_11436/2838455497.py:1: SyntaxWarning: invalid escape sequence '\s'
  leerzeichen = re.compile('\s+')
print(leerzeichen)
re.compile('\\s+')
leerzeichen.split("Hallo\nWelt!")
['Hallo', 'Welt!']
minus = re.compile("-+")
minus
re.compile(r'-+', re.UNICODE)
minus.split("Hallo Welt! Das ist -- wenn man so sagen kann -- ein Einschub.")
['Hallo Welt! Das ist ', ' wenn man so sagen kann ', ' ein Einschub.']

Pattern suchen und ersetzen#

import re
line = 'the quick brown fox jumped over a lazy dog'
line
'the quick brown fox jumped over a lazy dog'

Alle Wörter mit einem Buchstaben “o”:

o_woerter_re = re.compile(r'(\w*)o(\w*)')
o_woerter_re
re.compile(r'(\w*)o(\w*)', re.UNICODE)
o_woerter_match = o_woerter_re.search(line)

search liefert als Ergebnis ein Objekt zurück, vom Typ re.Match:

type(o_woerter_match)
re.Match
o_woerter_match
<re.Match object; span=(10, 15), match='brown'>
o_woerter_match.start()
10
o_woerter_match.end()
15
o_woerter_re.findall(line)
[('br', 'wn'), ('f', 'x'), ('', 'ver'), ('d', 'g')]

alle “o” durch ein “X” ersetzen, und den Wortteil vorne und hinten austauschen:

o_woerter_re.sub(r"\2X\1", line)
'the quick wnXbr xXf jumped verX a lazy gXd'

aus regex101#

test_str = ("""Der 24.12.2023 ist in diesem Jahr ein Sonntag. 
Der Unterricht geht bis Freitag 2023-12-22, weiter dann 2024.01.08. 
In 2024 gibt es sogar einen Donnerstag 2024-02-29, aber nicht 2024-04-31. 
Auch klar: Amerikaner notieren den Anschlag nine-eleven 9/11 mit 09/11/2001; 
Europäer notieren den 11. September 2001 mit 11-09-2001.\n
und das gibt es nicht: 2024-13-98""")
import re
iso_datum_pattern = re.compile(r"((\d\d\d\d)-(\d\d)-(\d\d))")
type(iso_datum_pattern)
re.Pattern
iso_datum_pattern
re.compile(r'((\d\d\d\d)-(\d\d)-(\d\d))', re.UNICODE)

search() liefert den ersten Treffer:

iso_datum_pattern.search(test_str)
<re.Match object; span=(80, 90), match='2023-12-22'>
iso_datum_pattern
re.compile(r'((\d\d\d\d)-(\d\d)-(\d\d))', re.UNICODE)

findall() liefert eine Liste aller Treffer:

alle_treffer = iso_datum_pattern.findall(test_str)
alle_treffer
[('2023-12-22', '2023', '12', '22'),
 ('2024-02-29', '2024', '02', '29'),
 ('2024-04-31', '2024', '04', '31'),
 ('2024-13-98', '2024', '13', '98')]
type(alle_treffer)
list

Substitute:

print(iso_datum_pattern.sub(r"\1\n   Tag: \4\n   Monat: \3\n   Jahr: \2\n", test_str))
Der 24.12.2023 ist in diesem Jahr ein Sonntag. 
Der Unterricht geht bis Freitag 2023-12-22
   Tag: 22
   Monat: 12
   Jahr: 2023
, weiter dann 2024.01.08. 
In 2024 gibt es sogar einen Donnerstag 2024-02-29
   Tag: 29
   Monat: 02
   Jahr: 2024
, aber nicht 2024-04-31
   Tag: 31
   Monat: 04
   Jahr: 2024
. 
Auch klar: Amerikaner notieren den Anschlag nine-eleven 9/11 mit 09/11/2001; 
Europäer notieren den 11. September 2001 mit 11-09-2001.

und das gibt es nicht: 2024-13-98
   Tag: 98
   Monat: 13
   Jahr: 2024