• Keine Ergebnisse gefunden

Skriptsprachen: Python Regular Expressions

N/A
N/A
Protected

Academic year: 2022

Aktie "Skriptsprachen: Python Regular Expressions"

Copied!
30
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Skriptsprachen: Python

Regular Expressions

Jan Krüger, Alexander Sczyrba

Technische Fakultät Universität Bielefeld

12. Februar 2018

(2)

Reguläre Ausdrücke

Was wir machen wollen OHNE irgendeinen Texteditor zu verwenden (STRG+Fist keine Textsuche):

Text-Dateien zeilenweise einlesen

Zeilen nach Mustern durchsuchen

Zeilen in Teilworte zerlegen

Textstücke ersetzen

(3)

Reguläre Ausdrücke

Was wir machen wollen OHNE irgendeinen Texteditor zu verwenden (STRG+Fist keine Textsuche):

Text-Dateien zeilenweise einlesen

Zeilen nach Mustern durchsuchen

Zeilen in Teilworte zerlegen

Textstücke ersetzen

(4)

Reguläre Ausdrücke

Was wir machen wollen OHNE irgendeinen Texteditor zu verwenden (STRG+Fist keine Textsuche):

Text-Dateien zeilenweise einlesen

Zeilen nach Mustern durchsuchen

Zeilen in Teilworte zerlegen

Textstücke ersetzen

(5)

Reguläre Ausdrücke

Was wir machen wollen OHNE irgendeinen Texteditor zu verwenden (STRG+Fist keine Textsuche):

Text-Dateien zeilenweise einlesen

Zeilen nach Mustern durchsuchen

Zeilen in Teilworte zerlegen

Textstücke ersetzen

(6)

Reguläre Ausdrücke

Beschreiben einfache Sprachen

„schwächste“ Chomsky-Grammatik

In Python: Regular Expressions (RE), nach Perl-Syntax

Regular Expressions in Python deutlich mächtiger als Reguläre Sprachen

(7)

Reguläre Ausdrücke

Wir arbeiten mit demre-Modul, dass uns die Funktionalität von Perl-RE zur Verfügung stellt.

In Python geht alles von einempattern-Objekt aus, das entsprechende Funktionen anbietet.

> i m p o r t re

> s t o r y = ’ In ␣ a ␣ h o l e ␣ in ␣ the ␣ g r o u n d ␣ t h e r e ␣ l i v e d ␣ a ␣ b o g g i t . ’

> p = re . c o m p i l e ( r " in " )

> m = p . m a t c h ( s t o r y ) # S u c h t am S t r i n g a n f a n g

> m # K e i n T r e f f e r - > N o n e

> m = p . s e a r c h ( s t o r y ) # S u c h t im g e s a m t e n S t r i n g

> m # Match - O b j e k t

< _ s r e . S R E _ M a t c h at 0 x 1 0 4 2 a 9 6 4 8 >

(8)

Pattern-Objekt

Das Pattern wird mit derre.compile(<RE_STR>, <FLAGS>)erstellt.

Das Pattern beginnt mit einem vorangestelltenr gefolgt von der eigentlichen RE als String (Bsp: re.compile(r"[a-Z]*"))

Häufigst verwendeterModifier (Flag):

re.IGNORECASE Ignoriere Groß- und Kleinschreibung Aus dem obigen Beispiel folgt:

re.compile(r"[a-z]*", re.IGNORECASE)

(9)

Match-Objekt

Auf demmatch-Objekt sind folgende Methoden definiert:

group() Rückgabewert: Der gematchte String start() Rückgabewert: Startindex des Matches

end() Rückgabewert: Endindex des Matches span() Rückgabewert: Start-/Endindex als Tupel

(10)

Match-Objekt

Wenn ein Treffer gefunden wurde, so wird ein match-Objekt zurückgeliefert, ansonstenNone.

Generelles Vorgehen zur RE-Verarbeitung in Python

> p = re . c o m p i l e ( < PATTERN >)

> m = p . m a t c h ( ’ s t r i n g ␣ g o e s ␣ h e r e ’ )

> if m :

> p r i n t ’ M a t c h ␣ f o u n d : ␣ ’ , m . g r o u p () , ’ ␣ w i t h ␣ i n d i c e s ␣ ’ , m . s p a n ()

> e l s e :

> p r i n t ’ No ␣ m a t c h ’

(11)

Pattern – findall() & finditer()

Um alle Vorkommen zu finden, verwendetfindall() bzw.

finditer():

> p = re . c o m p i l e ( ’ \ d + ’ )

> p . f i n d a l l ( ’ 12 ␣ d r u m m e r s ␣ d r u m m i n g , ␣ 11 ␣ p i p e r s ␣ piping ,

␣ ␣ 10 ␣ l o r d s ␣ a - l e a p i n g ’ )

[ ’ 12 ’ , ’ 11 ’ , ’ 10 ’ ] # A l l e g e f u n d e n e n M a t c h e s als L i s t e

> i t e r a t o r = p . f i n d i t e r ( ’ 12 ␣ d r u m m e r s ␣ d r u m m i n g , ␣ 11 ␣ ... ␣ 10 ␣ ... ’ )

> i t e r a t o r # I t e r a t o r mit match - O b j e k t e n

< c a l l a b l e - i t e r a t o r o b j e c t at 0 x ... >

> for m a t c h in i t e r a t o r :

> p r i n t m a t c h . s p a n () (0 , 2)

(22 , 24) (29 , 31)

(12)

sub() – Patternersetzung

Mitsub(<REPL>, <STR>[, count=0]) (Substitute) können Pattern mitREPLersetzt werden. Die maximale Ersetzungshäufigkeit kann mit countangegeben werden.

> t = ’ 12 ␣ d r u m m e r s ␣ d r u m m i n g , ␣ 11 ␣ p i p e r s ␣ piping , . . . ’

> p = re . c o m p i l e ( ’ umm ’ )

> p . sub ( " ift " , t )

’ 12 ␣ d r i f t e r s ␣ d r i f t i n g , ␣ 11 ␣ p i p e r s ␣ piping , . . . ’

> p . sub ( " r i f t " , t , c o u n t =1)

’ 12 ␣ d r i f t e r s ␣ d r u m m i n g , ␣ 11 ␣ p i p e r s ␣ piping , . . . ’

(13)

Übung – Suchen und Ersetzen

Die nachfolgend genannten Textdateien findet ihr in

/vol/lehre/python/. Es handelt sich um Theaterstücke von Wayne Anthoney.

Wieviele Zeilen von romeo.txtenthalten das Wort „Gold“?

Gib die jeweiligen Indexpositionen der Treffer pro Zeile aus.

Ersetze in dem Texteric.txtdas Wort „Estragon“ durch „Basil“ und

„Vladimir“ durch „Ilych“.

(14)

RegEx

Alternativen:r"Huey|Dewey|Louie"

Gruppierung: r"(Hu|Dew)ey|Louie"

Quantoren

r " ab ? a " # aa , aba

r " ab * a " # aa , aba , abba , abbba , abbbba , ...

r " ab + a " # aba , abba , abbba , abbbba , ...

r " ab {3 ,6} a " # abbba , abbbba , abbbbba , a b b b b b b a r " a ( bab )+ a " # ababa , ababbaba , a b a b b a b b a b a , ...

(15)

RegEx

Zeichenklassen

r " h e l l o \ s + w o r l d " # w h i t e s p a c e r " es ␣ ist ␣ \ d + ␣ Uhr " # d i g i t s r " name : ␣ \ w + " # l e t t e r s ( w o r d s )

„Gegenteile“: \S, \D, \W

Selbst erstellte Zeichenklasse

r " M [ ea ][ iy ] er " # Meier , Meyer , Maier , M a y e r r " [ a - z ]{2 ,8} " # Account - N a m e n

r " [ A - Z ][^0 -9]+ "

Passt auf alles: .

(16)

Anker

Muster an bestimmte Position binden:

Zeilenanfang/-ende

r " ^ L O C U S .+ " # L O C U S Z e i l e aus G e n B a n k D a t e i r " \ s + $ " # all t r a i l i n g w h i t e s p a c e

r " ^\ d + ␣ \ d + ␣ \ d + $ " # 3 d c o o r d

Wortzwischenraum

r " \ bmit \ b " # " n i c h t mit mir " , " K o m m e n Sie mit !"

r " \ bmit \ B " # " m i t t e n d r i n " , n i c h t " v e r m i t t e l n "

(17)

Übung – Zeilen extrahieren

Lies die Datei/etc/serviceszeilenweise ein.

Gib alle Zeilen aus, die sich auf das ProtokollTCPbeziehen.

Gib alle Zeilen aus, die einen Service deviieren (also keine Kommentarzeile sind).

Gib alle Zeilen aus, die eine vier- oder fünfstellige Port-Nummer enthalten.

Wie können alle Zeilen aus romeo.txtextrahiert werden, in denen die Worte „club“ oder „clubs“ vorkommen, aber nicht „clubroom“?

(18)

Pattern Capturing

Bis jetzt: Muster kommen im Text vor!

Aber: Wie sah der Treffer aus?→ findall nur halbe Wahrheit

Interessanten Bereich markieren:

r " ^ L O C U S \ s +(\ S +) "

r " ^ V E R S I O N \ s +(\ S + ) \ . ( \ d +)\ s + GI :(\ d +) $ "

Treffer landen bei match immatch-Objekt

> p = re . c o m p i l e ( r ’ a ( b (( c ) d )) ’ )

> m = p . m a t c h ( ’ a b c d ’ )

> m . g r o u p () # G e s a m t e r M a t c h - > m . g r o u p (0)

’ a b c d ’

> m . g r o u p s () # M a r k i e r t e G r u p p e n ( ’ bcd ’ , ’ cd ’ , ’ c ’ )

> m . g r o u p (2)

’ cd ’

Quantoren richtig einsetzen:(\w)+ !=(\w+)

(19)

Pattern Capturing

Bis jetzt: Muster kommen im Text vor!

Aber: Wie sah der Treffer aus?→ findall nur halbe Wahrheit

Interessanten Bereich markieren:

r " ^ L O C U S \ s +(\ S +) "

r " ^ V E R S I O N \ s +(\ S + ) \ . ( \ d +)\ s + GI :(\ d +) $ "

Treffer landen bei match immatch-Objekt

> p = re . c o m p i l e ( r ’ a ( b (( c ) d )) ’ )

> m = p . m a t c h ( ’ a b c d ’ )

> m . g r o u p () # G e s a m t e r M a t c h - > m . g r o u p (0)

’ a b c d ’

> m . g r o u p s () # M a r k i e r t e G r u p p e n ( ’ bcd ’ , ’ cd ’ , ’ c ’ )

> m . g r o u p (2)

’ cd ’

Quantoren richtig einsetzen:(\w)+ !=(\w+)

(20)

Pattern Capturing

Bis jetzt: Muster kommen im Text vor!

Aber: Wie sah der Treffer aus?→ findall nur halbe Wahrheit

Interessanten Bereich markieren:

r " ^ L O C U S \ s +(\ S +) "

r " ^ V E R S I O N \ s +(\ S + ) \ . ( \ d +)\ s + GI :(\ d +) $ "

Treffer landen bei match immatch-Objekt

> p = re . c o m p i l e ( r ’ a ( b (( c ) d )) ’ )

> m = p . m a t c h ( ’ a b c d ’ )

> m . g r o u p () # G e s a m t e r M a t c h - > m . g r o u p (0)

’ a b c d ’

> m . g r o u p s () # M a r k i e r t e G r u p p e n ( ’ bcd ’ , ’ cd ’ , ’ c ’ )

> m . g r o u p (2)

’ cd ’

Quantoren richtig einsetzen:(\w)+ !=(\w+)

(21)

Pattern Capturing

Bis jetzt: Muster kommen im Text vor!

Aber: Wie sah der Treffer aus?→ findall nur halbe Wahrheit

Interessanten Bereich markieren:

r " ^ L O C U S \ s +(\ S +) "

r " ^ V E R S I O N \ s +(\ S + ) \ . ( \ d +)\ s + GI :(\ d +) $ "

Treffer landen bei match immatch-Objekt

> p = re . c o m p i l e ( r ’ a ( b (( c ) d )) ’ )

> m = p . m a t c h ( ’ a b c d ’ )

> m . g r o u p () # G e s a m t e r M a t c h - > m . g r o u p (0)

’ a b c d ’

> m . g r o u p s () # M a r k i e r t e G r u p p e n ( ’ bcd ’ , ’ cd ’ , ’ c ’ )

> m . g r o u p (2)

’ cd ’

Quantoren richtig einsetzen:(\w)+ !=(\w+)

(22)

Pattern Capturing

Bis jetzt: Muster kommen im Text vor!

Aber: Wie sah der Treffer aus?→ findall nur halbe Wahrheit

Interessanten Bereich markieren:

r " ^ L O C U S \ s +(\ S +) "

r " ^ V E R S I O N \ s +(\ S + ) \ . ( \ d +)\ s + GI :(\ d +) $ "

Treffer landen bei match immatch-Objekt

> p = re . c o m p i l e ( r ’ a ( b (( c ) d )) ’ )

> m = p . m a t c h ( ’ a b c d ’ )

> m . g r o u p () # G e s a m t e r M a t c h - > m . g r o u p (0)

’ a b c d ’

> m . g r o u p s () # M a r k i e r t e G r u p p e n ( ’ bcd ’ , ’ cd ’ , ’ c ’ )

> m . g r o u p (2)

(23)

Übung – Romeo, oh Romeo...

Inromeo.txtfindet sich die Regieanweisung der „ROMEO enters“.

Extrahiert die Namen der Personen, die auf diese Weise die Bühne betreten. Verwendet einen geeigneten Datentyp, um die Personen lediglich einmalig zu speichern.

(24)

Pattern Capturing

Das Muster muss vollständig passen:

> p = re . c o m p i l e ( r ’ a ( b (( c ) d )) ’ )

> m = p . m a t c h ( ’ abcd ’ )

> type ( m ) N o n e T y p e

Unterschied zwischen groupingundcapturing:

r " \ d +( -\ d +)* " # -12345 r " \ d +(?: -\ d +)* " # 1 2 3 4 5

(25)

Übung – Servicelist as a Service

Lies/etc/servicesein. Stelle die Informationen über die Dienste etwas umgangssprachlicher dar.

Für die Zeile ftp 21/tcpsoll die Ausgabe wie folgt aussehen:

Der Dienst "ftp"verwendet TCP auf Port 21

Eventuelle weitere Informationen (Alias-Name oder Kommentare) sollen ignoriert werden.

(26)

Greedy Matches

Was passiert, wenn Pattern nicht eindeutig sind?

> t = " a a a a a a a a a a "

> p = re . c o m p i l e ( r " ( a +)( a +) " )

> m = p . m a t c h ( t )

> m . g r o u p () # ???

> m . g r o u p s () # ???

Ausprobieren: r " ( a +)( a *) " r " ( a *)( a +) " r " ( a *)( a *) " r " ( a ?)( a *) " r " ( a {2 ,4})( a *) "

Setze hinter den ersten Quantoren: +? *? ?? {2,4}?

(27)

Greedy Matches

Was passiert, wenn Pattern nicht eindeutig sind?

> t = " a a a a a a a a a a "

> p = re . c o m p i l e ( r " ( a +)( a +) " )

> m = p . m a t c h ( t )

> m . g r o u p () # ???

> m . g r o u p s () # ???

Ausprobieren:

r " ( a +)( a *) "

r " ( a *)( a +) "

r " ( a *)( a *) "

r " ( a ?)( a *) "

r " ( a {2 ,4})( a *) "

Setze hinter den ersten Quantoren: +? *? ?? {2,4}?

(28)

Greedy Matches

Was passiert, wenn Pattern nicht eindeutig sind?

> t = " a a a a a a a a a a "

> p = re . c o m p i l e ( r " ( a +)( a +) " )

> m = p . m a t c h ( t )

> m . g r o u p () # ???

> m . g r o u p s () # ???

Ausprobieren:

r " ( a +)( a *) "

r " ( a *)( a +) "

r " ( a *)( a *) "

r " ( a ?)( a *) "

(29)

Text zerteilen

Sequenzkomponenten zu einen String vereinen:

> l = [ ’ b ’ , 1 , ’ f f e e g ’ ]

> " " . j o i n ( map ( str , l ))

’ b 1 f f e e g ’

Entgegengesetzte Funktion mit RE: split(string[, count=0])

Trennung durch Pattern:

> s t o r y = " In ␣ a ␣ h o l e ␣ in ␣ the ␣ g r o u n d ␣ t h e r e ␣ l i v e d ␣ a ␣ h o b b i t . "

> p = re . c o m p i l e ( r " \ s " )

> p . s p l i t ( s t o r y )

[ ’ In ’ , ’ a ’ , ’ h o l e ’ , ’ in ’ , ’ the ’ , ’ g r o u n d ’ , ’ t h e r e ’ , ’ l i v e d ’ ,

’ a ’ , ’ h o b b i t . ’ ]

(30)

Übung – Sätzlein, trenn dich!

Trenne den Satz

„In a hole in the ground there lived a hobbit.“

mit den folgenden Mustern. Welche Worte entstehen dabei?

r " ␣ "

r " "

r " \ s * "

r " \ b "

r " \ B "

Referenzen

ÄHNLICHE DOKUMENTE

GNFAs are like NFAs but the transition labels can be arbitrary regular expressions over the input alphabet. q 0

GNFAs are like NFAs but the transition labels can be arbitrary regular expressions over the input alphabet. q 0

I DFAs, NFAs and regular grammars can all describe exactly the regular languages.. I Are there other concepts with the

Pumping lemma: use a necessary property that holds for all regular languages. Picture courtesy of imagerymajestic

C3.1 Regular Expressions C3.2 Pumping Lemma C3.3 Summary.!. C3.1

In den Dateien Ue12a.txt, Ue12b.txt und Ue12c.txt sind gewichtete gerichtete Graphen wie folgt gespeichert:. • Die Knoten des Graphen sind

Beispiel: Der Regul¨ are Ausdruck ’a+’ beschreibt die Menge aller Zeichenketten, die aus einem oder mehreren. ’a’ bestehen: {’a’, ’aa’, ’aaa’,

o (Zeile unterhalb einfügen, Einfügemodus) O (Zeile oberhalb einfügen, Einfügemodus) cw (Rest des Wortes löschen, Einfügemodus) c$ (Rest der Zeile löschen, Einfügemodus). in