RegExp-Kurs 06: Punkt, Quantoren

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

RegExp-Kurs 06: Punkt, Quantoren

Beitrag von Meillo » 22.05.2022 09:07:43

Kursuebersicht


Teil 06: Punkt, Quantoren


Im Falle von EREs haben wir nun alle Moeglichkeiten kennengelernt mit denen man literale Zeichen matchen kann ... mit einer Ausnahmen, die nun folgt:


Punkt

Eigentlich haette das Metazeichen Punkt thematisch besser zu den Zeichenklassen gepasst, da er nichts anderem entspricht als einer Zeichenklasse, die alle Zeichen enthaelt. Oder anders gesprochen: der Punkt matcht ein beliebiges Zeichen.

Statt dieser Zeichenklasse (die alle Zeichen enthaelt):

Code: Alles auswählen

[[:print:][:cntrl:]]
kann man also auch einfach
schreiben. Das ist ungemein praktisch, gerade da REs in der Praxis meist nicht vollkommen exakt sein muessen und der Punkt einem dann eine Menge Tipparbeit spart.


Der vorige Teil mit den Zeichenklassen war allerdings schon sehr lang und der Punkt passt von den Anwendungsszenarien auch gut zu den hier nun vorgestellten Quantoren, da man ihn dort am oeftesten antrifft.


Aber rekapitulieren wir erst einmal kurz:

- Wir koennen literale Zeichen direkt matchen und sie ggf. escapen, falls es Metazeichen sind.

- Wir koennen mit Zeichenklassen eines von mehreren Zeichen bzw. nun mit dem Punkt ein beliebiges Zeichen matchen. Der Punkt und die vordefinierten Zeichenklassenbereiche erlauben es uns auch und unbekannte Zeichen zu matchen.

- Wir koennen Alternationen nutzen, um eine von mehreren REs zu matchen. Mittels Klammern geht das auch fuer Teil-REs.


Was wir noch nicht koennen ist eine Variabilitaet in der *Laenge* des gematchten Textes. Bislang koennen wir anhand der RE schon im Voraus sagen wie viele Zeichen die Matches umfassen werden. Durch Alternationen koennen das verschiedene Laengen sein, aber wir kennen sie alle.

Wollen wir aber beispielsweise ``beliebig viel Whitespace'' matchen, dann ist uns das bislang noch nicht moeglich. Diese Moeglichkeit lernen wir nun kennen.



Quantoren

Mit Quantoren kann man angeben wie oft die davor stehende Teil-RE wiederholt vorkommen darf bzw. muss. Es gibt vier Arten von Quantoren in EREs. Sie alle beziehen sich auf die direkt davor stehende RE-Komponente, das kann ein literales Zeichen sein oder eine Zeichenklasse oder ein geklammerter Unterausdruck. Sie beziehen sich also auf die kleinstmoegliche Sinneinheit, die vor ihnen steht. Kurzum kann man sagen: Ein Quantor bezieht sich auf das Konstrukt unmittelbar davor das fuer ein einzelnes Zeichen steht (d.h. literales Zeichen, escaptes Zeichen, Zeichenklasse). Nur im Falle eines Unterausdrucks bezieht er sich auf mehrere Zeichen.


Stern

Der Stern ist der einzige Quantor, der bei allen RE-Varianten verfuegbar ist. Er ist stets ein Metazeichen und wird von allen Implementierungen unterstuetzt.

Ein Stern bedeutet, dass die davorstehende Sinneinheit beliebig oft (null bis unendlich) wiederholt werden kann.

Die RE:

Code: Alles auswählen

Aa*h!
matcht damit die Worte:

Code: Alles auswählen

Ah!
Aah!
Aaah!
Aaaah!
Aaaaah!
Aaaaaah!
Aaaaaaah!
Aaaaaaaah!
Aaaaaaaaah!
usw.
Der Stern bezieht sich hier nur auf das `a', da das die kleinste Sinneinheit ist.


Plus

Oft passender aber nicht in allen RE-Implementierungen verfuegbar (oder es muss escapet werden) ist das Plus. Dieses aehnelt dem Stern, steht aber fuer mindestens ein Vorkommen bis unendlich viele.

Die RE:

Code: Alles auswählen

A[ua]+!
matcht damit auf:

Code: Alles auswählen

Au!
Aa!
Auu!
Aua!
Aau!
Aaa!
Aaua!
Auau!
Auuu!
Aaaa!
Aaau!
Aauuauauuauauuauauuauuuuauuuauaaaauuuuuu!
usw.
Sie matcht aber nicht auf:

Fragezeichen

Auch das Fragezeichen ist nicht in allen RE-Implementierungen verfuegbar (oder muss escapet werden). Es steht fuer eine ``Wiederholung'' von null- oder einmal und damit eigentlich nicht fuer eine Wiederholung sondern macht die vorhergehende Teil-RE optional.

So koennen mit folgender RE:

Code: Alles auswählen

colou?r
die die britische als auch die amerikanische Schreibweise gemacht werden:

Code: Alles auswählen

colour
color
Das Fragezeichen kann stets durch eine Alternation mit einem leeren Teil (was jedoch nicht vollstaendig portabel ist) ersetzt werden:

Code: Alles auswählen

colo(u|)r

Intervalle

Zuletzt die allgemeinste Form eines Quantors, der alle drei obigen Quantoren ersetzen kann. Intervalle werden mit geschweiften Klammern notiert. (Von wenigen Ausnahmen abgesehen sind Intervalle ueberall verfuegbar. Mit ihnen kann man also auch Plus und Fragezeichen ersetzen, falls es diese in einer RE-Variante nicht gibt. Die geschweiften Klammern muessen in manchen RE-Varianten escapet werden.)

Die geschweiften Klammern koennen:

1) ... genau eine Zahl enthalten. Das bedeutet, dass der davorstehende Teil-Ausdruck genau so oft wiederholt werden muss. Diese Form ist nur Syntactic Sugar, der Schreibarbeit spart, denn den Ausdruck:

Code: Alles auswählen

[0-9]{3}
kann man natuerlich jederzeit auch so schreiben:

Code: Alles auswählen

[0-9][0-9][0-9]
Hier ein Beispiel mit Unterausdruck fuer eine Zeile des langen Schlussteils eines bekannten Liedes:

Code: Alles auswählen

Na(, na na){4}, hey, Jude
2) ... mit einem Komma getrennt, zwei Zahlen enthalten. Diese legen dann die Mindest- und Maximalzahl an Wiederholungen fest:

Code: Alles auswählen

(Na(, na na){4}, Hey, Jude){8,24}
3) ... eine Zahl und ein Komma enthalten. Das bedeutet, dass es keine Obergrenze gibt.

Wenn die Band also so richtig im Flow und das Publikum gut ist, dann geht auch mit offenem Ende:

Code: Alles auswählen

(Na(, na na){4}, Hey, Jude){8,}
:-D


Gierigkeit

Bei Quantoren (aber auch bei der Alternation) hat die RE-Engine manchmal die Wahl, mehr oder weniger zu matchen. Es ist festgelegt, dass REs immer so viel wie moeglich matchen. POSIX nennt das den fruehesten laengsten Treffer (``the longest of the leftmost matches'').

Die RE:
wird folglich so viele `a' wie moeglich matchen. Wenn es keine `a' hat, dann wird sie einen leeren String matchen, aber wenn sie `a' findet, dann beginnt sie beim ersten, das sie findet, und nimmt ab da so viele wie sie kann.



Aufgaben:

1) Matche mit einer RE allen Input.

2) Extrahiere mit `egrep -o' alle Zahlen aus einem Text.

3) Matche in einem XML-Input mit einer RE (ohne Alternation) die Beginn- und Ende-Tags `<h1>' und `</h1>'.

4) Schreibe die entsprechenden Intervallausdruecke fuer die drei anderen Quantoren: * + ?

5) Erklaere die RE: `**'. Auf was wird sie matchen?

6) ``Bananen?'' -- Dies ist keine Frage, sondern?

7) Matche alles bis ``ENDE'' (inklusive).

8) Matche den Inhalt eines Single-Quoted Strings (dieser kann das Single-Quote nicht enthalten).

9) Matche einen Satz, d.h. von einem Grossbuchstaben bis zum naechsten Satzendezeichen. (Zweimal drueber nachdenken und testen. Der erste Ansatz ist nicht unbedingt ausreichend!)

10) Matche grosse Geldwerte mit Tausendertrenner.

11) Finde ein sinnhaftes Praxisbeispiel fuer eine RE mit Punkt aber ohne Quantoren.
Use ed once in a while!

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von Meillo » 22.05.2022 09:10:12

Mit ist letzte Woche leider das RL dazwischengegraetscht, darum kommt dieser Teil erst jetzt, mit einer Woche Verspaetung.
Use ed once in a while!

Huo
Beiträge: 605
Registriert: 26.11.2017 14:03:31
Wohnort: Freiburg

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von Huo » 22.05.2022 20:31:26

Als vorhin im im Radio eine Sendung über Gendersprache lief, fiel mir spontan eine Zusatzaufgabe zum Gendersternchen ein, die gut zum oben behandelten Lernstoff passt:

12) Finde einen Regulären Ausdruck (ohne Alternation), der "Lehrerzimmer", "Lehrerinnenzimmer" und "Lehrer*innenzimmer" matcht. :wink:

Benutzeravatar
MSfree
Beiträge: 10686
Registriert: 25.09.2007 19:59:30

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von MSfree » 22.05.2022 20:45:35

Huo hat geschrieben: ↑ zum Beitrag ↑
22.05.2022 20:31:26
... "Lehrerinnenzimmer"...
Innenzimmer für Lehrer oder Zimmer für Lehrerinnen?
*SCNR*

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von Meillo » 22.05.2022 20:55:50

Huo hat geschrieben: ↑ zum Beitrag ↑
22.05.2022 20:31:26
Als vorhin im im Radio eine Sendung über Gendersprache lief, fiel mir spontan eine Zusatzaufgabe zum Gendersternchen ein, die gut zum oben behandelten Lernstoff passt:

12) Finde einen Regulären Ausdruck (ohne Alternation), der "Lehrerzimmer", "Lehrerinnenzimmer" und "Lehrer*innenzimmer" matcht. :wink:
Tolle Idee!

Die Aufgabe kann auch gerne noch auf die alternativen Genderzeichen (Doppelpunkt und Unterstrich) erweitert werden: ``Lehrer:innenzimmer'', ``Lehrer_innenzimmer''.

(Der Zusatzhinweis -- ohne Alternation -- wird keine perfekten Loesungen zulassen, aber das ist nicht schlimm, weil man das in dem Fall auftretende Problem dann auch diskutieren kann.)

MSfree hat geschrieben: ↑ zum Beitrag ↑
22.05.2022 20:45:35
Huo hat geschrieben: ↑ zum Beitrag ↑
22.05.2022 20:31:26
... "Lehrerinnenzimmer"...
Innenzimmer für Lehrer oder Zimmer für Lehrerinnen?
*SCNR*
Lehrerinneninnenzimmer :mrgreen:
Use ed once in a while!

inne
Beiträge: 3273
Registriert: 29.06.2013 17:32:10
Lizenz eigener Beiträge: GNU General Public License
Kontaktdaten:

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von inne » 23.05.2022 00:30:15

Vorab: Bitte bedenkt, das ich selten bis kaum und nur sehr rudimentär RE benutzte und keine wirklichen Erfahrungen habe. Dennoch ein Lösungsversuch von mir, auch damit Meillo Feedback hat ;-)
1) Matche mit einer RE allen Input.

Code: Alles auswählen

grep '.*'
Passe auf ein beliebiges Zeichen und das dann beliebig oft (auch keinmal), was dann Alles sein sollte?
2) Extrahiere mit `egrep -o' alle Zahlen aus einem Text.

Code: Alles auswählen

egrep -o "[0-9]+"
3) Matche in einem XML-Input mit einer RE (ohne Alternation) die Beginn- und Ende-Tags `<h1>' und `</h1>'.
Nein, es gibt xpath dafür!
4) Schreibe die entsprechenden Intervallausdruecke fuer die drei anderen Quantoren: * + ?
So: egrep ".{0,}", egrep ".{1,}", egrep ".{0,1}"?
5) Erklaere die RE: `**'. Auf was wird sie matchen?
Ich kann es nicht wirklich erklären. Auf sowas wie diesen Phantasieausdruck würde ich vermuten: (''*)*
6) ``Bananen?'' -- Dies ist keine Frage, sondern?
Es passt auf Banane und Bananen also Einzahl und Mehrzahl und meint sowas wie Banane(n). Denn das n am Ende ist optional und muss nicht gegeben sein.
7) Matche alles bis ``ENDE'' (inklusive).

Code: Alles auswählen

$ echo Ist es das ENDE, oder doch nicht und es kommt noch ein ENDE? | egrep -o '^.*ENDE'
Ist es das ENDE, oder doch nicht und es kommt noch ein ENDE

Code: Alles auswählen

echo Das ist das ENDE\; endgültig\! | egrep -o '^.*ENDE'
Das ist das ENDE
8) Matche den Inhalt eines Single-Quoted Strings (dieser kann das Single-Quote nicht enthalten).

Code: Alles auswählen

echo "'My WiFi password is 24446666688888888, just to say 12345678 if someone ask :-)'"| egrep -o "'[^']*'"
9) Matche einen Satz, d.h. von einem Grossbuchstaben bis zum naechsten Satzendezeichen. (Zweimal drueber nachdenken und testen. Der erste Ansatz ist nicht unbedingt ausreichend!)
egrep -o '[[:upper:]][^.!?]*[.!?]'
Passe auf 1 Grossbuchstaben, dann auf 1 nicht Satzendezeichen und das beliebig oft (auch keinmal) und dann auf 1 Satzendezeichen.
10) Matche grosse Geldwerte mit Tausendertrenner.
egrep -o '[0-9.,-]+' | egrep "\.[0-9]{3}"
Passe auf eine Zahl mit Tausendertrenner und optional die Nachkommastellen, dann auf Tausenderfolgen :-)
Also diese Aufgabe finde ich schon schwirig!
11) Finde ein sinnhaftes Praxisbeispiel fuer eine RE mit Punkt aber ohne Quantoren.
egrep "^.\)"
Passt auf sowas wie Auflisten wie hier die *ersten* wichtigsten Aufgaben. Also 1), 2), 3), a), b), c) usw. Ich habe hier weiter keine Praxiserfahrung als dass mir etwas einfallen würde. Für etwas gebraucht, an das ich mich jetzt erinnere habe ich es wohl noch nicht.

Huo
Beiträge: 605
Registriert: 26.11.2017 14:03:31
Wohnort: Freiburg

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von Huo » 25.05.2022 01:43:36

Meine Lösungen:
1) Matche mit einer RE allen Input.
2) Extrahiere mit `egrep -o' alle Zahlen aus einem Text.

Code: Alles auswählen

egrep -o '[0-9]+' zahlen.txt
Wegen der Option -o erhalte ich mit

Code: Alles auswählen

egrep -o '[0-9]*' zahlen.txt
ebenfalls das gewünschte Ergebnis, da laut Manpage von grep die Option -o die "passenden (nicht leeren [!]) Teile" ausgibt.
3) Matche in einem XML-Input mit einer RE (ohne Alternation) die Beginn- und Ende-Tags `<h1>' und `</h1>'.

Code: Alles auswählen

</?h1>
4) Schreibe die entsprechenden Intervallausdruecke fuer die drei anderen Quantoren: * + ?
* -> {0,} oder {,}
+ -> {1,}
? -> {0,1} oder {,1}
5) Erklaere die RE: `**'. Auf was wird sie matchen?
Uff! Meine erste Vermutung: Der erste Stern wird literal interpretiert, da nichts vor ihm steht, der zweite Stern hingegen als Quantor. Die RE "sollte" also auf beliebig viele aufeinander folgende Sterne matchen, einschließlich null Sterne. grep -o '**' hält sich auch schön brav an meine Vermutung, nicht jedoch egrep -o '**', das nichts ausgibt.

Zweite Vermutung: Der erste Stern wird als Quantor auf den leeren String angewendet. Der zweite Stern ist dann redundant, also verzichtbar. Im Grunde ist sogar der erste Stern verzichtbar, da sowohl die mehrmalige Wiederholung als auch das Weglassen eines leeren (!) Strings sinnlos ist. Diese Hypothese wird dadurch bestätigt, dass egrep '**' alle Zeilen eines Textes ausgibt (der leere String ist halt Teilmenge aller Zeilen), egrep -o '**' jedoch nichts (weil es keine passenden nicht leeren Teile gibt, die ausgegeben werden könnten). Das gleiche Verhalten zeigt egrep für die REs '*' und '' (leere RE).
6) ``Bananen?'' -- Dies ist keine Frage, sondern?
... matcht wegen des Quantors "?" "Banane" und "Bananen", also Singular und Plural von "Banane".
7) Matche alles bis ``ENDE'' (inklusive).

Code: Alles auswählen

.*ENDE
Hier ist .* besser als .+, da ENDE ja auch das erste Wort der Zeile sein könnte.
8) Matche den Inhalt eines Single-Quoted Strings (dieser kann das Single-Quote nicht enthalten).

Code: Alles auswählen

egrep "'[^']*'"
Es werden allerdings die Single Quotes mit gematcht. Einen Regulären Ausdruck, der nur den String innerhalb der Quotes matcht, habe ich nicht gefunden (vielleicht gar nicht möglich?). Der Teilausdruck "[^']*" (statt ".*") sorgt dafür, dass nicht über mehr als zwei Single Quotes hinweg gematcht wird.
9) Matche einen Satz, d.h. von einem Grossbuchstaben bis zum naechsten Satzendezeichen. (Zweimal drueber nachdenken und testen. Der erste Ansatz ist nicht unbedingt ausreichend!)
Mein erster Ansatz war '[A-Z].*[.!?]', aber das erfasst ggf. gierig mehrere Sätze hintereinander. Wie gefordert bis zum NÄCHSTEN Satzende matcht

Code: Alles auswählen

[A-Z][^.!?]*[.!?]
10) Matche grosse Geldwerte mit Tausendertrenner.

Code: Alles auswählen

[0-9]{1,3}(\.[0-9]{3})*
Erläuterung: Vor dem ersten Punkt (oder bei Beträgen unter 1.000) können ein bis drei Ziffern stehen. Darauf können sich beliebig viele Punkte, jeweils gefolgt von genau drei Ziffern, anschließen.
Um Schreibweisen mit führender Null auszuschließen, könnte man den Regulären Ausdruck dann noch angepassen:

Code: Alles auswählen

[1-9][0-9]{0,2}(\.[0-9]{3})*
11) Finde ein sinnhaftes Praxisbeispiel fuer eine RE mit Punkt aber ohne Quantoren.
Ein wirklich sinnhaftes natürlichsprachiges Beispiel ist m.E. nicht möglich wegen der Beliebigkeit, die der Punkt repräsentiert. Man könnte aber mit

Code: Alles auswählen

egrep '"."'
nach doppelt gequoteten Strings suchen, die genau ein Zeichen umfassen – etwa in einem Text, der einzelne so gequotete Zeichen erklärt, definiert oder kodiert ...

Meine Zusatzaufgabe:
12) Finde einen Regulären Ausdruck (ohne Alternation), der "Lehrerzimmer", "Lehrerinnenzimmer" und "Lehrer*innenzimmer" matcht. :wink:

Code: Alles auswählen

Lehrer(\*?innen)?zimmer
Oder um die Genderzeichen "_" und ":" erweitert:

Code: Alles auswählen

Lehrer([*:_]?innen)?zimmer

Benutzeravatar
tegula
Beiträge: 439
Registriert: 04.06.2004 13:51:04
Lizenz eigener Beiträge: MIT Lizenz

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von tegula » 25.05.2022 13:18:20

Meillo hat geschrieben: ↑ zum Beitrag ↑
22.05.2022 09:07:43
1) Matche mit einer RE allen Input.

Code: Alles auswählen

 $ egrep --line-number "." schwaebische-kunde.txt
Ausgabe: NoPaste-Eintrag41690, Zeile 17-75.
Meillo hat geschrieben: ↑ zum Beitrag ↑
22.05.2022 09:07:43
2) Extrahiere mit `egrep -o' alle Zahlen aus einem Text.

Code: Alles auswählen

$ ## Eingabetext anzeigen
$ cat -n a2.txt
     1  [Komma als Dezimaltrennzeichen]
     2  Hans kauft beim Bäcker 2 Brote und 10 Brötchen und 4 Crossaints. 
     3  Hans' Rechnung beim Bäcker beträgt 15,99 Euro. 
     4  Hans zahlt mit einem 20-Euro-Schein. Er erhält 4,01 Euro als Rückgeld.
     5
     6  [Punkt als Dezimaltrenner]
     7  Hans buys 2 breads and 10 rolls and 4 crossaints from the baker.
     8  Hans' bill to the baker is 15.99 euros.
     9  Hans pays with a 20-euro note.
    10  He receives 4.01 euros as change.
$ ## Zahlen mit 'egrep -o' extrahieren (sowohl Komma und Punkt als Dezimaltrenner und/oder Tausendertrenner erlaubt)
$ egrep -o --line-number "[[:digit:]]+[.,]*[[:digit:]]*" a2.txt
2:2
2:10
2:4
3:15,99
4:20
4:4,01
7:2
7:10
7:4
8:15.99
9:20
10:4.01
$ 

Meillo hat geschrieben: ↑ zum Beitrag ↑
22.05.2022 09:07:43
3) Matche in einem XML-Input mit einer RE (ohne Alternation) die Beginn- und Ende-Tags `<h1>' und `</h1>'.

Code: Alles auswählen

$ ## Input herunterladen
$ wget -O "Forum_RegEx-Kurs_Teil_06.html" https://debianforum.de/forum/viewtopic.php?p=1302386
--2022-05-24 13:53:46--  https://debianforum.de/forum/viewtopic.php?p=1302386
Auflösen des Hostnamens debianforum.de (debianforum.de)… 142.132.203.155, 2a01:4f8:261:4fe1::2
Verbindungsaufbau zu debianforum.de (debianforum.de)|142.132.203.155|:443 … verbunden.
HTTP-Anforderung gesendet, auf Antwort wird gewartet … 200 OK
Länge: nicht spezifiziert [text/html]
Wird in »Forum_RegEx-Kurs_Teil_06.html« gespeichert.
 
Forum_RegEx-Kurs_Teil_06.html                   [ <=>                                                                                        ]  60,12K  --.-KB/s    in 0,05s  
 
2022-05-24 13:53:47 (1,27 MB/s) - »Forum_RegEx-Kurs_Teil_06.html« gespeichert [61568]
 
$
$ ## Ausgabe: Nur Tags, ohne eingeschlossenen Text
$ egrep -o --line-number "</?h1>" Forum_RegEx-Kurs_Teil_06.html
55:<h1>
55:</h1>
$ 
$ ## Ausgabe: Tags, einschließlich dem eingeschlossenen Text
$ egrep -o --line-number "(<h1>)+(.)*(</h1>)+" Forum_RegEx-Kurs_Teil_06.html
55:<h1>debianforum.de</h1>
$ 
Meillo hat geschrieben: ↑ zum Beitrag ↑
22.05.2022 09:07:43
4) Schreibe die entsprechenden Intervallausdruecke fuer die drei anderen Quantoren: * + ?

Code: Alles auswählen

$ ## Eingabe anzeigen
$ cat -n a4.txt
     1  Xa
     2  X96
     3  Zb
     4  Zaa
     5  Yaaaaaaaaaa
$
$ ## "*" (beliebige Zahl an Wiederholungen, auch 0 Wiederholungen möglich)
$ egrep -o --line-number "(.)a{,}" a4.txt
1:Xa
2:X
2:9
2:6
3:Z
3:b
4:Zaa
5:Yaaaaaaaaaa
$ egrep -o --line-number "(.)a*" a4.txt # Kontrolle mit Sternchen-Operator
1:Xa
2:X
2:9
2:6
3:Z
3:b
4:Zaa
5:Yaaaaaaaaaa
$
$ ## "+" (mindestens eine Wiederholung)
$ egrep -o ".(a{1,})" a4.txt
Xa
Zaa
Yaaaaaaaaaa
$ egrep -o --line-number "(.)a+" a4.txt # Kontrolle mit plus-Operator
1:Xa
4:Zaa
5:Yaaaaaaaaaa
$
$ ## "?" (vorheriges Zeichen darf einmalig vorkommen, muss aber nicht vorkommen)
$ egrep -o --line-number "(.)a{0,1}" a4.txt
1:Xa
2:X
2:9
2:6
3:Z
3:b
4:Za
4:a
5:Ya
5:aa
5:aa
5:aa
5:aa
5:a
$ egrep -o --line-number "(.)a?" a4.txt # Kontrolle mit Fragezeichen-Operator
1:Xa
2:X
2:9
2:6
3:Z
3:b
4:Za
4:a
5:Ya
5:aa
5:aa
5:aa
5:aa
5:a
Meillo hat geschrieben: ↑ zum Beitrag ↑
22.05.2022 09:07:43
5) Erklaere die RE: `**'. Auf was wird sie matchen?
Sie wird auf jedes Zeichenfolge (bzw. auf jede Zeile einer Datei) matchen, da die Aussage "Die Zeilenfolge besteht aus mindestens 0 Wiederholungen und maximal unendlich vielen Wiederholungen von 'keinem Zeichen' (), gefolgt von (erneut) mindestens 0 Wiederholungen und maximal unendlich vielen Wiederholungen von 'keinem Zeichen' ()" scheinbar (?) für jede Zeichenfolge gilt.
Befehle und Ausgabe: NoPaste-Eintrag41690, Zeile 211 - 333).
Meillo hat geschrieben: ↑ zum Beitrag ↑
22.05.2022 09:07:43
6) ``Bananen?'' -- Dies ist keine Frage, sondern?
.. ein RE, der sowohl auf "Banane" als auch auf "Bananen" matcht.

Code: Alles auswählen

$ cat -n a6.txt
     1  Annanas
     2  Banan
     3  Banane
     4  Bananen
     5  Bananenn
     6  Bananem
$ egrep -o --line-number "Bananen?" a6.txt
3:Banane
4:Bananen
5:Bananen
6:Banane
$ 
Meillo hat geschrieben: ↑ zum Beitrag ↑
22.05.2022 09:07:43
7) Matche alles bis ``ENDE'' (inklusive).

Code: Alles auswählen

$ ## Eingabetext anzeigen
$ cat -n a7.txt
     1  Das ist eine Geschichte.
     2  Sie ist leider nicht sehr lang.
     3  Sie ist schon jetzt zu ENDE. Ganz zu ENDE.
     4  Ja das ist wirklich schon das Ende bzw. ENDE. Ja genau: Das ENDE :(
$ ## bis zum _letzten_ 'ENDE' jeder Zeile
$ egrep -o --line-number "(.)*(ENDE){1}" a7.txt
3:Sie ist schon jetzt zu ENDE. Ganz zu ENDE
4:Ja das ist wirklich schon das Ende bzw. ENDE. Ja genau: Das ENDE
$ ## bis zum _letzten_ 'ENDE' in jener Zeile, in der das Wort 'ENDE' zum ersten mal auftritt
$ egrep -o --max-count 1 --line-number "(.)*(ENDE){1}" a7.txt
3:Sie ist schon jetzt zu ENDE. Ganz zu ENDE
$ ## bis zum _ersten_ 'ENDE' der jeder Zeile
$ ### --> Habe hierfür leider keine Lösung herausgefinden können.
$ ## bis zum _allerersten_ 'ENDE' des Textes
$ ### --> Habe hierfür leider keine Lösung herausgefinden können.
$ 
Meillo hat geschrieben: ↑ zum Beitrag ↑
22.05.2022 09:07:43
8) Matche den Inhalt eines Single-Quoted Strings (dieser kann das Single-Quote nicht enthalten).

Code: Alles auswählen

$ ## Gesamter Zeichenkette (einschließlich des Single-Quoted-String) definiernen und in einer Datei abspeichern
$ printf "Das Folgende ist ein 'Single-Quoted String'. Danach ist es wieder ein normaler String" > a8_input.txt
$ printf "\n"
 
$ ## Reguläre Ausdruck definieren und in eine Datei abspeichern
$ printf "(')(.)*(')" > a8_regex.txt
$ printf "\n"
 
$ ## Abgespeicherten regulären Ausdruck auf abspeicherte Zeichenkette anwenden
$ egrep -o -f a8_regex.txt a8_input.txt
'Single-Quoted String'
$ 
Meillo hat geschrieben: ↑ zum Beitrag ↑
22.05.2022 09:07:43
9) Matche einen Satz, d.h. von einem Grossbuchstaben bis zum naechsten Satzendezeichen. (Zweimal drueber nachdenken und testen. Der erste Ansatz ist nicht unbedingt ausreichend!)

Code: Alles auswählen

$ ## Satz anzeigen
$ cat a9.txt
Das ist der erste Satz. Und was ist das? Ein weiterer Satz!
$
$ ## egrep ausführen bzw. RE anwenden
$ ### **Anmerkung:** Einzelne Anführungszeichen (statt doppelte Anführungszeichen) sind hier scheinbar (?) notwendig, weil die Shell sonst eine Fehlermeldung ausgibt ("[...] event not found")
$ egrep -o '[[:upper:]][^?.!:]*([?.!:])' a9.txt
Das ist der erste Satz.
Und was ist das?
Ein weiterer Satz!
$ 
Meillo hat geschrieben: ↑ zum Beitrag ↑
22.05.2022 09:07:43
10) Matche grosse Geldwerte mit Tausendertrenner.

Code: Alles auswählen

$ ## Eingabe anzeigen
$ cat -n a10.txt
     1  100000
     2  100000 Euro
     3  10.000 Euro
     4  70.000 €
     5  537,28 Euro
     6  890.785,71€
     7  7.55 Euro
$ ## egrep ausführen bzw. RE anwenden
$ egrep -o --line-number "([[:digit:]]|,)*([.][[:digit:]]{3,3})(,[[:digit:]]{2})?([[:blank:]])?(Euro|€)*" a10.txt
3:10.000 Euro
4:70.000 €
6:890.785,71€
$ 
Meillo hat geschrieben: ↑ zum Beitrag ↑
22.05.2022 09:07:43
11) Finde ein sinnhaftes Praxisbeispiel fuer eine RE mit Punkt aber ohne Quantoren.
Was wirklich sinnvolles ist mir leider nicht eingefallen :(.

Code: Alles auswählen

$ #' **Antwort bzw. Beispiel:** Kontrolle, ob eine gewählte Abkürzung eine Länge von genau drei Zeichen einhält.
$ 
$ ## Eingabe anzeigen
$ cat -n a11.txt
     1  g23
     2  abX
     3  AbHUi5g
     4  125
     5  14 h
$ 
$ ## egrep ausführen bzw. RE anwenden
$ egrep -o --line-number "^(...)$" a11.txt
1:g23
2:abX
4:125
$ 
Huo hat geschrieben: ↑ zum Beitrag ↑
25.05.2022 01:43:36
Meine Zusatzaufgabe:
12) Finde einen Regulären Ausdruck (ohne Alternation), der "Lehrerzimmer", "Lehrerinnenzimmer" und "Lehrer*innenzimmer" matcht. :wink:

Code: Alles auswählen

Lehrer(\*?innen)?zimmer
Oder um die Genderzeichen "_" und ":" erweitert:

Code: Alles auswählen

Lehrer([*:_]?innen)?zimmer

Code: Alles auswählen

$ # Eingabe anzeigen
$ cat -n a12.txt
     1  Lehrerzimmer
     2  Lehrerinnenzimmer
     3  Lehrer*innenzimmer
     4  Schülerzimmer
     5  Schüler*innenzimmer
     6  Lehrzimmer
     7  Lehrer:innenzimmer
     8  Lehrer_innenzimmer
$ 
$ ## Variante 1: _Ohne_ Alteration
$ egrep -o --line-number "Lehrer[*_:]?[i]?[n]?[n]?[e]?[n]?zimmer" a12.txt
1:Lehrerzimmer
2:Lehrerinnenzimmer
3:Lehrer*innenzimmer
7:Lehrer:innenzimmer
8:Lehrer_innenzimmer
$ 
$ ## Variante 2: _Mit_ Alteration
$ egrep -o --line-number "(Lehrerzimmer|Lehrerinnenzimmer|Lehrer[*_:]innenzimmer)" a12.txt
1:Lehrerzimmer
2:Lehrerinnenzimmer
3:Lehrer*innenzimmer
7:Lehrer:innenzimmer
8:Lehrer_innenzimmer
$ 

inne
Beiträge: 3273
Registriert: 29.06.2013 17:32:10
Lizenz eigener Beiträge: GNU General Public License
Kontaktdaten:

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von inne » 26.05.2022 10:42:51

Für Aufgabe 10), finde Große Geldwerte habe ich nun doch noch einen RE der mir passt.

Code: Alles auswählen

egrep -o '\-?[0-9]{1,3}(\.[0-9]{3})*(,[0-9]+)?(EUR|€|Euro)'
Weil ,00 z.B. einfach kein großer Wert ist. Und an die Maßeinheit hatte ich gar nicht gedacht. Aber false-positiv hat dieser Ausdruck bestimmt immernoch.
Zuletzt geändert von inne am 28.05.2022 09:18:48, insgesamt 1-mal geändert.

Huo
Beiträge: 605
Registriert: 26.11.2017 14:03:31
Wohnort: Freiburg

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von Huo » 26.05.2022 11:55:27

inne hat geschrieben: ↑ zum Beitrag ↑
26.05.2022 10:42:51

Code: Alles auswählen

egrep -o '[^0-9,.]-?[0-9]{1,3}(\.[0-9]{3})*(,[0-9]+)?(EUR|€|Euro)'
Hm, kannst Du erklären, was die Zeichenklasse [^0-9,.] am Anfang Deiner RE bezwecken soll? Sie scheint die Ausgabe eines korrekten Eurobetrags zu unterdrücken, wenn er am Anfang der Zeile steht. Und wenn er nicht am Anfang steht, wird etwas unschön das vorangehende Zeichen mit ausgegeben:

Code: Alles auswählen

$ echo "123,45 EUR" | egrep -o '[^0-9,.]-?[0-9]{1,3}(\.[0-9]{3})*(,[0-9]+)? (EUR|€|Euro)'
$ echo "Betrag:123,45 EUR" | egrep -o '[^0-9,.]-?[0-9]{1,3}(\.[0-9]{3})*(,[0-9]+)? (EUR|€|Euro)'
:123,45 EUR
$ echo "123,45 EUR" | egrep -o '[0-9]{1,3}(\.[0-9]{3})*(,[0-9]+)? (EUR|€|Euro)'
123,45 EUR

Huo
Beiträge: 605
Registriert: 26.11.2017 14:03:31
Wohnort: Freiburg

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von Huo » 26.05.2022 12:22:28

tegula hat geschrieben: ↑ zum Beitrag ↑
25.05.2022 13:18:20

Code: Alles auswählen

$ egrep -o --line-number "([[:digit:]]|,)*([.][[:digit:]]{3,3})(,[[:digit:]]{2})?([[:blank:]])?(Euro|€)*" a10.txt
Auch bei Deiner Lösung zu Aufgabe (10) verstehe ich den Anfang der RE nicht ganz, nämlich die Alternation mit Stern-Quantor ([[:digit:]]|,)*. Damit werden unsinnige führende Kommas mit ausgegeben, sowie falsche Betragsschreibweisen mit mehr als drei Ziffern vor dem ersten Tausenderpunkt:

Code: Alles auswählen

$ echo ",,,1234.567" | egrep -o --line-number "([[:digit:]]|,)*([.][[:digit:]]{3,3})(,[[:digit:]]{2})?([[:blank:]])?(Euro|€)*"
1:,,,1234.567

inne
Beiträge: 3273
Registriert: 29.06.2013 17:32:10
Lizenz eigener Beiträge: GNU General Public License
Kontaktdaten:

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von inne » 26.05.2022 16:47:36

Huo hat geschrieben: ↑ zum Beitrag ↑
26.05.2022 11:55:27
Und wenn er nicht am Anfang steht, wird etwas unschön das vorangehende Zeichen mit ausgegeben:
Genau das wollte ich damit eigentlich unterbinden :| Aber Du hast recht, das erste Zeichen wird mit ausgegeben, da habe ich nicht richtig mit gedacht, wie REs funktionieren, es ist kein Test.
Zuletzt geändert von inne am 26.05.2022 17:13:38, insgesamt 1-mal geändert.

Benutzeravatar
tegula
Beiträge: 439
Registriert: 04.06.2004 13:51:04
Lizenz eigener Beiträge: MIT Lizenz

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von tegula » 26.05.2022 17:07:04

Huo hat geschrieben: ↑ zum Beitrag ↑
26.05.2022 12:22:28
tegula hat geschrieben: ↑ zum Beitrag ↑
25.05.2022 13:18:20

Code: Alles auswählen

$ egrep -o --line-number "([[:digit:]]|,)*([.][[:digit:]]{3,3})(,[[:digit:]]{2})?([[:blank:]])?(Euro|€)*" a10.txt
Auch bei Deiner Lösung zu Aufgabe (10) verstehe ich den Anfang der RE nicht ganz, nämlich die Alternation mit Stern-Quantor ([[:digit:]]|,)*. Damit werden unsinnige führende Kommas mit ausgegeben, sowie falsche Betragsschreibweisen mit mehr als drei Ziffern vor dem ersten Tausenderpunkt:

Code: Alles auswählen

$ echo ",,,1234.567" | egrep -o --line-number "([[:digit:]]|,)*([.][[:digit:]]{3,3})(,[[:digit:]]{2})?([[:blank:]])?(Euro|€)*"
1:,,,1234.567
:oops:
Vielen Dank Huo! :THX:
Habe auf Grundlage Deines Posts folgendes an meinem Lösungsvorschlag korrigiert:
  1. Die Zeichenfolge muss mit einem Wortanfang beginnen: \<
  2. Der Zeichenfolge muss mit mindestens einer und maximal drei Dezimalzahlen beginnen, nach denen kein Komma folgt: [[:digit:]]{1,3}
  3. Darauf muss mindestens eine Wiederholung von "Punk-Dezimalzahl-Dezimalzahl-Dezimalzahl" folgen: ([.][[:digit:]]{3})+
  4. Die Zeichenfolge muss zwingend mit "Euro" bzw. "€" enden: (Euro|€) (--> ohne Sternchen-Operator dahinter)

Code: Alles auswählen

$ ## Eingabe anzeigen
$ cat -n a10_neu.txt
     1  ,,,1234.567
     2  ,,,1234.567€
     3  234.567 234.567 Euro 234.567€  234.567 € 234.567 Stk
     4  100000 10.000 Euro 100000 Euro 
     5  ,234.567 Euro ,234.567
     6  70.000 €
     7  537,28 Euro
     8  890.785,71€
     9  7.55 Euro
    10  99.100.111,57 €
$ 
$ ## egrep ausführen bzw. regulären Ausdruck auf Eingabe anwenden
$ egrep -o --line-number "\<[[:digit:]]{1,3}([.][[:digit:]]{3})+(,[[:digit:]]{2})?([[:blank:]])?(Euro|€)+" a10_neu.txt
3:234.567 Euro
3:234.567€
3:234.567 €
4:10.000 Euro
5:234.567 Euro
6:70.000 €
8:890.785,71€
10:99.100.111,57 €
$ 
Weiterhin vorhandenes Problem meines Vorschlags: Führende Nullen, können zu einem fehlerhaften Match führen :(

Code: Alles auswählen

$ printf '000.000.567,73 Euro' | egrep -o "\<[[:digit:]]{1,3}([.][[:digit:]]{3})+(,[[:digit:]]{2})?([[:blank:]])?(Euro|€)+"
000.000.567,73 Euro
$

Huo
Beiträge: 605
Registriert: 26.11.2017 14:03:31
Wohnort: Freiburg

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von Huo » 26.05.2022 17:57:31

tegula hat geschrieben: ↑ zum Beitrag ↑
26.05.2022 17:07:04

Code: Alles auswählen

$ egrep -o --line-number "\<[[:digit:]]{1,3}([.][[:digit:]]{3})+(,[[:digit:]]{2})?([[:blank:]])?(Euro|€)+" a10_neu.txt
3:234.567 Euro
3:234.567€
3:234.567 €
4:10.000 Euro
5:234.567 Euro
6:70.000 €
8:890.785,71€
10:99.100.111,57 €
$ 
Das sieht mir doch gut aus! Ich hab's mir bei meiner Lösung ja im Vergleich zu Dir und inne sehr einfach gemacht, indem ich Meillos Aufgabe so aufgefasst habe, dass erstens auch kleine Beträge unter Tausend erlaubt sind, zweitens Centbeträge hinter dem Komma nicht gefragt sind und drittens auch nicht die Euro-Bezeichnung. :oops:
tegula hat geschrieben: ↑ zum Beitrag ↑
26.05.2022 17:07:04
Weiterhin vorhandenes Problem meines Vorschlags: Führende Nullen, können zu einem fehlerhaften Match führen :(
Vielleicht könntest Du aus meiner Lösung den Ansatz übernehmen, führende Nullen auszuschließen? In Deine RE eingebaut:

Code: Alles auswählen

\<[1-9][[:digit:]]{0,2}([.][[:digit:]]{3})+(,[[:digit:]]{2})?([[:blank:]])?(Euro|€)?

Benutzeravatar
tegula
Beiträge: 439
Registriert: 04.06.2004 13:51:04
Lizenz eigener Beiträge: MIT Lizenz

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von tegula » 28.05.2022 13:35:25

Huo hat geschrieben: ↑ zum Beitrag ↑
26.05.2022 17:57:31
tegula hat geschrieben: ↑ zum Beitrag ↑
26.05.2022 17:07:04
Weiterhin vorhandenes Problem meines Vorschlags: Führende Nullen, können zu einem fehlerhaften Match führen :(
Vielleicht könntest Du aus meiner Lösung den Ansatz übernehmen, führende Nullen auszuschließen? In Deine RE eingebaut:

Code: Alles auswählen

\<[1-9][[:digit:]]{0,2}([.][[:digit:]]{3})+(,[[:digit:]]{2})?([[:blank:]])?(Euro|€)?
Danke! Der Nachteil dieses Vorgehens scheint zu sein, dass nun alle Geldwerte, deren linkeste Ziffer eine Null ist, als 'zu klein' ausgeschlossen werden, undabhängig davon, ob der Wert tatsächlich kleiner als 1000 Euro ist :(

Code: Alles auswählen

$ printf '010.000.567,73 Euro'  | egrep -o "\<[1-9][[[:digit:]]{0,2}([.][[:digit:]]{3})+(,[[:digit:]]{2})?([[:blank:]])?(Euro|€)+"
$ 
Grundsätzliche Frage: Ist denn eine alleinige Lösung von Aufgabe 10 mittels regulärem Ausdruck -- also ohne den numerischen Teil zu extrahieren und ihn anschließend als Zahl zu behandeln (Shell) bzw. ihn in eine Zahl umzuwandeln (R, Python etc.) -- überhaupt möglich?

Huo
Beiträge: 605
Registriert: 26.11.2017 14:03:31
Wohnort: Freiburg

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von Huo » 28.05.2022 14:28:48

tegula hat geschrieben: ↑ zum Beitrag ↑
28.05.2022 13:35:25
Der Nachteil dieses Vorgehens scheint zu sein, dass nun alle Geldwerte, deren linkeste Ziffer eine Null ist, als 'zu klein' ausgeschlossen werden, undabhängig davon, ob der Wert tatsächlich kleiner als 1000 Euro ist :(
Ja, ich glaube, ich verstehe, was Du meinst: Werte kleiner als 1 Euro, wie z.B. 0,49 Euro werden nicht gematcht. Vorschlag: Mit einer Alternation ließe sich eine einzelne Null vor dem Komma berücksichtigen:

\<([1-9][[:digit:]]{0,2}([.][[:digit:]]{3})+|0)(,[[:digit:]]{2})?([[:blank:]])?(Euro|€)?

Ha, die RE entwickelt sich immer mehr zum Ungetüm :wink: . Verlangt man zusätzlich, dass keine einzeln stehende Null ohne Cent-Betrag gematcht werden darf (während für Werte größer/gleich 1,00 EUR der Cent-Betrag optional bleiben soll), wird die Lösung vollends unübersichtlich 8O :

\<([1-9][[:digit:]]{0,2}([.][[:digit:]]{3})+(,[[:digit:]]{2})?|0,[[:digit:]]{2})([[:blank:]])?(Euro|€)?

Benutzeravatar
tegula
Beiträge: 439
Registriert: 04.06.2004 13:51:04
Lizenz eigener Beiträge: MIT Lizenz

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von tegula » 28.05.2022 15:08:02

Wenn ich Meillos Aufgabenstellung (Aufgabe 10) richtig verstehe, soll 0,49 Euro ("Null Euro und Neunundvierzig Cent") sowieso nicht gemacht werden, da dieser Betrag kleiner als 1.000 Euro ("Eintausend Euro und Null Cent") ist, oder?

Was ich eigentlich gemeint habe: Hat der Betrag mindestens eine führende Nulle und und ist der Betrag (gleichzeitig) größer als 1.000 Euro ("Eintausend Euro und Null Cent"), so matched der RE nicht, obwohl aus der Aufgabenstellung abgeleitet werden kann, dass de RE (auch) in diesem Fall matchen soll.

Ehrlichgesagt bin ich mit Aufgabe 10 ziemlich überfordert :(.

EDIT (28.05.2022, 15:55 Uhr): Problembeschreibung korrigiert. ALT: "Hat der Betrag mindestens zwei führende Nullen und [...]". NEU (Korrektur): Hat der Betrag mindestens eine führende Null und [...]"
Zuletzt geändert von tegula am 28.05.2022 15:57:21, insgesamt 2-mal geändert.

Huo
Beiträge: 605
Registriert: 26.11.2017 14:03:31
Wohnort: Freiburg

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von Huo » 28.05.2022 15:42:55

O, sorry, ich hatte Deinen vorigen Beitrag nicht richtig zu Ende gelesen, wo Du ja ein Beispiel anführst:
tegula hat geschrieben: ↑ zum Beitrag ↑
28.05.2022 13:35:25

Code: Alles auswählen

$ printf '010.000.567,73 Euro'  | egrep -o "\<[1-9][[[:digit:]]{0,2}([.][[:digit:]]{3})+(,[[:digit:]]{2})?([[:blank:]])?(Euro|€)+"
Da haben wir wohl die ganze Zeit etwas an einander vorbeigeredet? Du willst, wenn ich es richtig verstehe, einen Wert wie 010.000,99 Euro (auch mit führender Null) als zulässig matchen, nicht jedoch beispielsweise den Wert 000.000.567,73 Euro – während ich alle führenden Nullen grundsätzlich ausschließen wollte.

Ja, auch ich finde die Aufgabe 10 ziemlich anspruchsvoll – warten wir ab, wie Meillo seine Aufgabe selbst interpretiert. :?

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von Meillo » 28.05.2022 15:51:17

Huo hat geschrieben: ↑ zum Beitrag ↑
28.05.2022 15:42:55
Ja, auch ich finde die Aufgabe 10 ziemlich anspruchsvoll – warten wir ab, wie Meillo seine Aufgabe selbst interpretiert. :?
Der Meillo lehnt sich entspannt zurueck und verfolgt mit Begeisterung die Diskussion und die Ueberlegungen, die sich um die Aufgabe entwickeln. ;-)

Es ist toll wie schoen man hier sieht, dass eine aus Anwendersicht erstmal ganz einfache Aufgabenstellung (Tausendertrenner) in der Umsetzung aus Informatikersicht viel mehr Komplexitaet hat als zuerst geglaubt.

Wie schonmal geschrieben, sind mir Musterloesungen recht egal. Es geht nicht um richtig oder falsch, sondern darum, dass ihr nachdenkt und etwas lernt. Genau das tut ihr gerade und damit loest ihr die Aufgabe auf die beste Weise (egal wie eure Loesung dann konkret aussieht). :THX:

Damit ziehe ich ich nun wieder zurueck und ueberlasse euch weiter den Raum ... ;-)
Use ed once in a while!

Huo
Beiträge: 605
Registriert: 26.11.2017 14:03:31
Wohnort: Freiburg

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von Huo » 28.05.2022 17:40:12

Meillo hat geschrieben: ↑ zum Beitrag ↑
28.05.2022 15:51:17
Wie schonmal geschrieben, sind mir Musterloesungen recht egal. Es geht nicht um richtig oder falsch, sondern darum, dass ihr nachdenkt und etwas lernt.
Wofür ich bei dem RegExp-Kurs übrigens ganz allgemein ein Bewusstsein entwickle, ist die Schwierigkeit, meine REs effektiv zu testen. "False positives", also fälschlich gematchte nicht gesuchte Strings, übersehe ich dabei gewöhnlich leichter als "false negatives", also nicht gematchte korrekte Strings. Testen ist als Bestätigung zur eigenen Sicherheit wichtig, erspart mir aber nicht das Nachdenken und Analysieren. (Edit: Eine vorschnelle, scheinbare Bestätigung durch "schlampiges" Testen kann mich in falsche Sicherheit wiegen.)
tegula hat geschrieben: ↑ zum Beitrag ↑
25.05.2022 13:18:20

Code: Alles auswählen

$ ## Variante 1: _Ohne_ Alteration
$ egrep -o --line-number "Lehrer[*_:]?[i]?[n]?[n]?[e]?[n]?zimmer" a12.txt
Da ich mich für meine selbstgestellte Zusatzaufgabe mit verantwortlich fühle :wink: : Matcht die Lösung wirklich keine false positives?
Deine Lösung mit Alternation erscheint mir allerdings eindeutig korrekt:
tegula hat geschrieben: ↑ zum Beitrag ↑
25.05.2022 13:18:20

Code: Alles auswählen

$ egrep -o --line-number "(Lehrerzimmer|Lehrerinnenzimmer|Lehrer[*_:]innenzimmer)" a12.txt
@Meillo: Da Du oben meintest, dass meine Zusatzaufgabe keine perfekte Lösung ohne Alternation zulassen wird, bin ich natürlich auch neugierig, ob meine eigene Lösung mit verschachteltem "?"-Quantor false positives übersehen hat.
Huo hat geschrieben: ↑ zum Beitrag ↑
25.05.2022 01:43:36

Code: Alles auswählen

Lehrer([*:_]?innen)?zimmer
Meillo hat geschrieben: ↑ zum Beitrag ↑
28.05.2022 15:51:17
Der Meillo lehnt sich entspannt zurueck
Okay, für eine Weile kann ich das noch tolerieren ... :lol:

Benutzeravatar
tegula
Beiträge: 439
Registriert: 04.06.2004 13:51:04
Lizenz eigener Beiträge: MIT Lizenz

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von tegula » 28.05.2022 19:18:58

Huo hat geschrieben: ↑ zum Beitrag ↑
28.05.2022 17:40:12
tegula hat geschrieben: ↑ zum Beitrag ↑
25.05.2022 13:18:20

Code: Alles auswählen

$ ## Variante 1: _Ohne_ Alteration
$ egrep -o --line-number "Lehrer[*_:]?[i]?[n]?[n]?[e]?[n]?zimmer" a12.txt
Da ich mich für meine selbstgestellte Zusatzaufgabe mit verantwortlich fühle :wink: : Matcht die Lösung wirklich keine false positives?
Meine Lösung (ohne Alteration) ist tatsächlich fehlerhaft, da ich nicht die Zeichenfolge "innen" als Gesamtheit optional gemacht habe, sondern stattdessen (fälschlicherweise) jedes Element dieser Zeichenfolge (i,n,n,e,n) separat als optional definiert habe :oops:.

Code: Alles auswählen

$ # Aufgabe 12: 'Finde einen Regulären Ausdruck (ohne Alternation), der "Lehrerzimmer", "Lehrerinnenzimmer" und "Lehrer*innenzimmer" matcht'( https://debianforum.de/forum/viewtopic.php?p=1302422#p1302422 ).
$ 
$ ## (Neue bzw. ergänzte) Eingabe anzeigen
$ cat -n a12_neu.txt
     1  Lehrerzimmer
     2  Lehrerinnenzimmer
     3  Lehrer*innenzimmer
     4  Schülerzimmer
     5  Schüler*innenzimmer
     6  Lehrzimmer
     7  Lehrer:innenzimmer
     8  Lehrer_innenzimmer
     9  [AB HIER NEU]
    10  Lehrernnzimmer
    11  Lehrer*nnzimmer
    12  Lehrerizimmer
    13  Lehrer*enzimmer
    14  Lehrernzimmer
    15  Lehreriizimmer
    16  Lehrer*innennzimmer
$ 
$ ## Mein (fehlerhafter) Lösungsversuch ( https://debianforum.de/forum/viewtopic.php?p=1302655#p1302655 )
$ egrep -o --line-number "Lehrer[*_:]?[i]?[n]?[n]?[e]?[n]?zimmer" a12_neu.txt
1:Lehrerzimmer
2:Lehrerinnenzimmer
3:Lehrer*innenzimmer
7:Lehrer:innenzimmer
8:Lehrer_innenzimmer
10:Lehrernnzimmer
11:Lehrer*nnzimmer
12:Lehrerizimmer
13:Lehrer*enzimmer
14:Lehrernzimmer
$ 
$ ## Musterlösung von Huo ( https://debianforum.de/forum/viewtopic.php?p=1302616#p1302616 )
$ egrep -o --line-number "Lehrer([*:_]?innen)?zimmer" a12_neu.txt
1:Lehrerzimmer
2:Lehrerinnenzimmer
3:Lehrer*innenzimmer
7:Lehrer:innenzimmer
8:Lehrer_innenzimmer
$ 

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von Meillo » 28.05.2022 19:58:17

Huo hat geschrieben: ↑ zum Beitrag ↑
28.05.2022 17:40:12
Meillo hat geschrieben: ↑ zum Beitrag ↑
28.05.2022 15:51:17
Wie schonmal geschrieben, sind mir Musterloesungen recht egal. Es geht nicht um richtig oder falsch, sondern darum, dass ihr nachdenkt und etwas lernt.
Wofür ich bei dem RegExp-Kurs übrigens ganz allgemein ein Bewusstsein entwickle, ist die Schwierigkeit, meine REs effektiv zu testen. "False positives", also fälschlich gematchte nicht gesuchte Strings, übersehe ich dabei gewöhnlich leichter als "false negatives", also nicht gematchte korrekte Strings. Testen ist als Bestätigung zur eigenen Sicherheit wichtig, erspart mir aber nicht das Nachdenken und Analysieren.
Richtig. Die Frage ist, wie man dieses Problem loest.

Ich persoenlich loese solche Probleme durch Nachdenken, weil das halt einfach meine Art ist. In dem Fall hier frage ich mich, was es noch fuer andere Moeglichkeiten gibt. Sicherlich hilfreich sind Zufallsinputgeneratoren, dann muss man nur die gematchten Texte durchschauen und erkennt vieleicht schnell False Positives. Allerdings ist das natuerlich nur blindes Stochern nach einem zufaelligen Treffer und darum eher ineffizient. Sobald man halt anfaengt den Input besser auf die Erwartungen abzustimmen, fliesst das eigene Denkmodell mit all seinen blinden Flecken mit ein und behaelt damit die blinden Flecken bei. Viele Realdaten zu haben, auf die man die RE anwenden kann ist sicherlich der beste Fall.

Ansonsten muss man halt vorgehen wie beim Testen: Man muss sich von der Implementiererperspektive loesen und die Tester/Angreifer-Perspektive einnehmen. Mit diesem anderen Blick auf die RE versucht man dann Problemfaelle zu finden. Das geht aber nur wenn man mit einen anderem Blick darauf schaut.

Wegen all dem finde ich es wichtig, REs zu verstehen, weil man nur dann sie durchdenken kann. Trial'n'Error fuehrt zu der von dir beschriebenen Situation.

Huo hat geschrieben: ↑ zum Beitrag ↑
28.05.2022 17:40:12
tegula hat geschrieben: ↑ zum Beitrag ↑
25.05.2022 13:18:20

Code: Alles auswählen

$ ## Variante 1: _Ohne_ Alteration
$ egrep -o --line-number "Lehrer[*_:]?[i]?[n]?[n]?[e]?[n]?zimmer" a12.txt
Da ich mich für meine selbstgestellte Zusatzaufgabe mit verantwortlich fühle :wink: : Matcht die Lösung wirklich keine false positives?
Wie tegula selber erkannt hat ist diese Loesung nicht allzu gut. Man kann sehr einfach ein False Positive konstruieren: ``Lehrernnnzimmer''

Huo hat geschrieben: ↑ zum Beitrag ↑
28.05.2022 17:40:12
Deine Lösung mit Alternation erscheint mir allerdings eindeutig korrekt:
tegula hat geschrieben: ↑ zum Beitrag ↑
25.05.2022 13:18:20

Code: Alles auswählen

$ egrep -o --line-number "(Lehrerzimmer|Lehrerinnenzimmer|Lehrer[*_:]innenzimmer)" a12.txt
Das ist der einfachste aber auch redundanteste Weg.

Huo hat geschrieben: ↑ zum Beitrag ↑
28.05.2022 17:40:12
@Meillo: Da Du oben meintest, dass meine Zusatzaufgabe keine perfekte Lösung ohne Alternation zulassen wird, bin ich natürlich auch neugierig, ob meine eigene Lösung mit verschachteltem "?"-Quantor false positives übersehen hat.
Huo hat geschrieben: ↑ zum Beitrag ↑
25.05.2022 01:43:36

Code: Alles auswählen

Lehrer([*:_]?innen)?zimmer
Meine Meinung war falsch. :lol: Das ist mir bewusst geworden, wo ich deine -- sehr elegante, wie ich sagen muss -- Loesung gesehen habe. :THX: Entscheidend ist, dass die optionalen Teile verschachtelt sind, sonst hat man das gleiche Phaenomen wie bei tegulas erster Loesung.

Huo hat geschrieben: ↑ zum Beitrag ↑
28.05.2022 17:40:12
Meillo hat geschrieben: ↑ zum Beitrag ↑
28.05.2022 15:51:17
Der Meillo lehnt sich entspannt zurueck
Okay, für eine Weile kann ich das noch tolerieren ... :lol:
Ach, solange eggy, JTH und der Dino noch entspannt sind kann ich es ruhig noch etwas schleifen lassen. Aber sagt denen bloss nicht Bescheid, dass ich mir hier einen faulen Lenz mache! ;-)

(Und im Ernst: Gerade ist's fuer mich schwierig mal eine laengere Zeit fuer konzentrierte Arbeit zu finden. Das RL ist gerade vollgestopft. Ich fuerchte, dass ich den naechsten Teil wohl erst am Montag veroeffentlichen koennen werde. Aber er wird kommen, keine Sorge.)
Use ed once in a while!

Benutzeravatar
TRex
Moderator
Beiträge: 8038
Registriert: 23.11.2006 12:23:54
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: KA

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von TRex » 28.05.2022 23:40:33

Meillo hat geschrieben: ↑ zum Beitrag ↑
28.05.2022 19:58:17
Ich persoenlich loese solche Probleme durch Nachdenken, weil das halt einfach meine Art ist.
:lol: :mrgreen:
Jesus saves. Buddha does incremental backups.
Windows ist doof, Linux funktioniert nichtDon't break debian!Wie man widerspricht

tobo
Beiträge: 1964
Registriert: 10.12.2008 10:51:41

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von tobo » 29.05.2022 01:25:51

Und so geht es weiter im Alltag einer Wanderdüne...

Benutzeravatar
tegula
Beiträge: 439
Registriert: 04.06.2004 13:51:04
Lizenz eigener Beiträge: MIT Lizenz

Re: RegExp-Kurs 06: Punkt, Quantoren

Beitrag von tegula » 29.05.2022 12:43:52

Meillo hat geschrieben: ↑ zum Beitrag ↑
28.05.2022 19:58:17
(Und im Ernst: Gerade ist's fuer mich schwierig mal eine laengere Zeit fuer konzentrierte Arbeit zu finden. Das RL ist gerade vollgestopft. Ich fuerchte, dass ich den naechsten Teil wohl erst am Montag veroeffentlichen koennen werde. Aber er wird kommen, keine Sorge.)
Danke! Cool, dass du trotzdem den Kurs weitermachst :THX:

Antworten