[erledigt] Extended Regex mit Rückreferenzen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
paedubucher
Beiträge: 856
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

[erledigt] Extended Regex mit Rückreferenzen

Beitrag von paedubucher » 26.02.2024 17:06:47

Mit egrep kann ich folgendermassen eine IP-Adresse matchen:

Code: Alles auswählen

$ echo 127.0.0.1 | egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
127.0.0.1
Nun möchte ich den regulären Ausdruck schlanker machen, indem ich eine Rückreferenz verwende. Dabei umklammere ich das erste Segment [0-9]{1,3} und ersetze die weiteren Segmente durch die Referenz \1. Doch leider funktioniert das so nicht:

Code: Alles auswählen

$ echo 127.0.0.1 | egrep '([0-9]{1,3})\.\1\.\1\.\1'
[kein Match]
Begehe ich da einen Denkfehler (d.h. auf konzeptioneller Ebene) oder habe ich mich da bloss mit einzelnen Zeichen verhaspelt? Ich komme gerade nicht auf die Lösung :?
Zuletzt geändert von paedubucher am 26.02.2024 17:39:01, insgesamt 1-mal geändert.
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

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

Re: Extended Regex mit Rückreferenzen

Beitrag von tobo » 26.02.2024 17:12:10

paedubucher hat geschrieben: ↑ zum Beitrag ↑
26.02.2024 17:06:47
Doch leider funktioniert das so nicht:
Doch, das funktioniert schon:

Code: Alles auswählen

$ echo 127.127.127.127 | egrep '([0-9]{1,3})\.\1\.\1\.\1'
127.127.127.127
$

Benutzeravatar
paedubucher
Beiträge: 856
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

Re: Extended Regex mit Rückreferenzen

Beitrag von paedubucher » 26.02.2024 17:21:37

tobo hat geschrieben: ↑ zum Beitrag ↑
26.02.2024 17:12:10
paedubucher hat geschrieben: ↑ zum Beitrag ↑
26.02.2024 17:06:47
Doch leider funktioniert das so nicht:
Doch, das funktioniert schon:

Code: Alles auswählen

$ echo 127.127.127.127 | egrep '([0-9]{1,3})\.\1\.\1\.\1'
127.127.127.127
$
Mit 127.127.127.127 funktioniert es bei mir auch, aber nicht mit 127.0.0.1.
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

Benutzeravatar
heisenberg
Beiträge: 3567
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: Extended Regex mit Rückreferenzen

Beitrag von heisenberg » 26.02.2024 17:24:13

paedubucher hat geschrieben: ↑ zum Beitrag ↑
26.02.2024 17:21:37
Mit 127.127.127.127 funktioniert es bei mir auch, aber nicht mit 127.0.0.1.
Na. Dann ist der Fall doch klar. \1 bezieht sich auf die gefundene Zeichenkette durch den enthaltenen regulären Ausdruck und nicht auf den regulären Ausdruck selbst.
Jede Rohheit hat ihren Ursprung in einer Schwäche.

Benutzeravatar
Livingston
Beiträge: 1454
Registriert: 04.02.2007 22:52:25
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: 127.0.0.1

Re: Extended Regex mit Rückreferenzen

Beitrag von Livingston » 26.02.2024 17:30:25

Code: Alles auswählen

$ echo 127.1.1.1 | egrep '(([0-9]{1,3})\.?){4}'
127.1.1.1
Kleiner Haken: Würde auch mit einem abschließenden Punkt matchen
Der Hauptunterschied zwischen etwas, was möglicherweise kaputtgehen könnte und etwas, was unmöglich kaputtgehen kann, besteht darin, dass sich bei allem, was unmöglich kaputtgehen kann, falls es doch kaputtgeht, normalerweise herausstellt, dass es unmöglich zerlegt oder repariert werden kann.
Douglas Adams

Benutzeravatar
paedubucher
Beiträge: 856
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

Re: Extended Regex mit Rückreferenzen

Beitrag von paedubucher » 26.02.2024 17:35:46

heisenberg hat geschrieben: ↑ zum Beitrag ↑
26.02.2024 17:24:13
paedubucher hat geschrieben: ↑ zum Beitrag ↑
26.02.2024 17:21:37
Mit 127.127.127.127 funktioniert es bei mir auch, aber nicht mit 127.0.0.1.
Na. Dann ist der Fall doch klar. \1 bezieht sich auf die gefundene Zeichenkette durch den enthaltenen regulären Ausdruck und nicht auf den regulären Ausdruck selbst.
:facepalm: Da haben wir es!

Der Rückbezug ist inhaltlich und nicht als Regel zu verstehen!

Vielen Dank! :THX:
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

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

Re: Extended Regex mit Rückreferenzen

Beitrag von tobo » 26.02.2024 17:37:32

Livingston hat geschrieben: ↑ zum Beitrag ↑
26.02.2024 17:30:25

Code: Alles auswählen

$ echo 127.1.1.1 | egrep '(([0-9]{1,3})\.?){4}'
127.1.1.1
Kleiner Haken: Würde auch mit einem abschließenden Punkt matchen
Und auch Zahlenkolonnen ohne jeden Punkt. Dann eher sowas:

Code: Alles auswählen

grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}'

Benutzeravatar
paedubucher
Beiträge: 856
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

Re: Extended Regex mit Rückreferenzen

Beitrag von paedubucher » 26.02.2024 17:38:50

tobo hat geschrieben: ↑ zum Beitrag ↑
26.02.2024 17:37:32
Livingston hat geschrieben: ↑ zum Beitrag ↑
26.02.2024 17:30:25

Code: Alles auswählen

$ echo 127.1.1.1 | egrep '(([0-9]{1,3})\.?){4}'
127.1.1.1
Kleiner Haken: Würde auch mit einem abschließenden Punkt matchen
Und auch Zahlenkolonnen ohne jeden Punkt. Dann eher sowas:

Code: Alles auswählen

grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}'
Vielen Dank, das ist eine sinnvolle Lösung für das Problem!
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

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

Re: Extended Regex mit Rückreferenzen

Beitrag von Meillo » 26.02.2024 17:42:12

heisenberg hat geschrieben: ↑ zum Beitrag ↑
26.02.2024 17:24:13
paedubucher hat geschrieben: ↑ zum Beitrag ↑
26.02.2024 17:21:37
Mit 127.127.127.127 funktioniert es bei mir auch, aber nicht mit 127.0.0.1.
Na. Dann ist der Fall doch klar. \1 bezieht sich auf die gefundene Zeichenkette durch den enthaltenen regulären Ausdruck und nicht auf den regulären Ausdruck selbst.
So ist es, nur weil das so ist, kann man damit das passende HTML-Tag matchen:

Code: Alles auswählen

<([bi])>.*</\1>
@paedu: Du wuenschst dir, Schreibaufwand zu sparen; wuerde die Rueckreferenz so funktionieren, dann waere die Sprache zwar regulaer, aber weniger maechtig. Soweit ich mich mit der Theorie auskenne, sind Rueckverweise schon kontextbasiert und damit mehr als nur regulaer. Sie sind also ein Addon auf REs, darum werden sie von EREs eigentlich auch nicht unterstuetzt, wodurch man diese mit einem DFA implementieren kann. Rueckreferenzen brauchen einen NFA. Moderne ERE-Implementierungen arbeiten aber hybride, d.h. sie nutzen einen DFA, wenn moeglich, und switchen zu einem NFA, falls noetig. (Nagelt mich bitte auf nichts davon fest. Das ist nur mein bestes Halbwissen. ;-) )
Use ed once in a while!

HumiNi
Beiträge: 340
Registriert: 02.10.2014 21:46:18

Re: Extended Regex mit Rückreferenzen

Beitrag von HumiNi » 26.02.2024 18:14:34

paedubucher hat geschrieben: ↑ zum Beitrag ↑
26.02.2024 17:38:50
Und auch Zahlenkolonnen ohne jeden Punkt. Dann eher sowas:

Code: Alles auswählen

grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}'

Code: Alles auswählen

$ echo 555.666.777.888 | grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}'
555.666.777.888
:?
Zuletzt geändert von HumiNi am 28.02.2024 12:03:40, insgesamt 1-mal geändert.
Gedächtnis wie ein Rechen: Nur Mist bleibt hängen.

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

Re: [erledigt] Extended Regex mit Rückreferenzen

Beitrag von tobo » 26.02.2024 18:36:22

Es gab hier vor kurzem einen ausführlichen RegEx-Thread dazu, der sich dem Problem einigermaßen angenommen hat. Ich finde den aber jetzt gerade nicht, Livingston vielleicht schon.
Eine RegEx zur "Validierung" von IP-Adressen ist jedenfalls überall im Internet zu finden - die geht dann jedoch deutlich über ein paar Zeilenlängen hinaus.
Grob: Es macht einen Unterschied, ob ich eine IP-Adresse validieren will oder ob ich in einem Text mit validierten IPv4-Adressen diese finden will. Denn mit Zahlen <256 ist es nicht ansatzweise getan...

Benutzeravatar
Livingston
Beiträge: 1454
Registriert: 04.02.2007 22:52:25
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: 127.0.0.1

Re: [erledigt] Extended Regex mit Rückreferenzen

Beitrag von Livingston » 26.02.2024 19:30:58

tobo hat geschrieben: ↑ zum Beitrag ↑
26.02.2024 18:36:22
Es gab hier vor kurzem einen ausführlichen RegEx-Thread dazu, der sich dem Problem einigermaßen angenommen hat. Ich finde den aber jetzt gerade nicht, Livingston vielleicht schon.
Ich erinnere mich, dass wir mehrere Lösungen für IPv4 und IPv6 gefunden haben, aber keine optimal traf (zumindest, wenn ma es kurz und knapp halten möchte). Probleme bereiteten u.a. Wortgrenzen.
Ich melde mich nochmal, wenn ich den Thread gefunden habe.

GEFUNDEN :mrgreen:
Da isser: viewtopic.php?t=188495
Der Titel ist etwas missverständlich. IPv4 wird dort auch mit abgehakt.
Der Hauptunterschied zwischen etwas, was möglicherweise kaputtgehen könnte und etwas, was unmöglich kaputtgehen kann, besteht darin, dass sich bei allem, was unmöglich kaputtgehen kann, falls es doch kaputtgeht, normalerweise herausstellt, dass es unmöglich zerlegt oder repariert werden kann.
Douglas Adams

Benutzeravatar
Livingston
Beiträge: 1454
Registriert: 04.02.2007 22:52:25
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: 127.0.0.1

Re: [erledigt] Extended Regex mit Rückreferenzen

Beitrag von Livingston » 27.02.2024 18:30:37

tobo hat geschrieben: ↑ zum Beitrag ↑
26.02.2024 18:36:22
Eine RegEx zur "Validierung" von IP-Adressen ist jedenfalls überall im Internet zu finden - die geht dann jedoch deutlich über ein paar Zeilenlängen hinaus.
Grob: Es macht einen Unterschied, ob ich eine IP-Adresse validieren will oder ob ich in einem Text mit validierten IPv4-Adressen diese finden will. Denn mit Zahlen <256 ist es nicht ansatzweise getan...
Neben dem bekannten Format sind Angaben in anderen Zahlensystemen auch zugelassen (mindestens oktal und hexadezimal). Dazu kämen inhaltliche Prüfungen (reservierte Bereiche, lokale Netze, Multicast-Adressraum, usw.)
Man muss eben unterscheiden zwischen Syntax (formaler Mustersuche mit Regexen) und Semantik (Checken nach erlaubten/ Werten). Eine einfache Quick'n'Dirty-Lösung für zweiteres könnte so aussehen:

Code: Alles auswählen

#!/bin/bash
  #Überprüft IPv4-Adresse im ersten Argument auf Gültigkeit
   
  myip=( $(echo $1|tr "." " ") )
  for i in ${myip[*]}; do
      if [ $i -gt 255 ]; then
          echo "War wohl nix :P"
          exit 1
      fi
 done
 echo "Adresse gültig"
Der Hauptunterschied zwischen etwas, was möglicherweise kaputtgehen könnte und etwas, was unmöglich kaputtgehen kann, besteht darin, dass sich bei allem, was unmöglich kaputtgehen kann, falls es doch kaputtgeht, normalerweise herausstellt, dass es unmöglich zerlegt oder repariert werden kann.
Douglas Adams

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

Re: [erledigt] Extended Regex mit Rückreferenzen

Beitrag von tobo » 27.02.2024 18:59:18

Wobei man vielleicht auf 4 Werte und die dann gegen True und nicht gegen False prüfen sollte!?

Code: Alles auswählen

$ ./t.sh 1.2-3
./t.sh: line 6: [: 2-3: integer expression expected
Adresse gültig
$

Benutzeravatar
paedubucher
Beiträge: 856
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

Re: [erledigt] Extended Regex mit Rückreferenzen

Beitrag von paedubucher » 27.02.2024 19:08:03

Danke auch für die Ergänzungen, welche den Wertebereich der vier IPv4-Segmente korrekt überprüfen. Mir ging es eigentlich nur um den Regex-Mechanismus, wozu die IP-Adresse einfach ein Beispiel war.
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

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

Re: [erledigt] Extended Regex mit Rückreferenzen

Beitrag von tobo » 27.02.2024 20:03:28

Wie Livingston schon schrieb, gibt es da durchaus mehrere Darstellungsmöglichkeiten.
https://de.wikipedia.org/wiki/IPv4#Adressformat hat geschrieben:Eine IPv4-Adresse kann in dezimal, binär, oktal und hexadezimal sowohl in der Punkt- als auch in der Nichtpunktnotation dargestellt werden.
Per RegEx kann das schnell ausarten...

Benutzeravatar
Livingston
Beiträge: 1454
Registriert: 04.02.2007 22:52:25
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: 127.0.0.1

Re: [erledigt] Extended Regex mit Rückreferenzen

Beitrag von Livingston » 27.02.2024 23:32:11

tobo hat geschrieben: ↑ zum Beitrag ↑
27.02.2024 18:59:18
Wobei man vielleicht auf 4 Werte und die dann gegen True und nicht gegen False prüfen sollte!?

Code: Alles auswählen

$ ./t.sh 1.2-3
./t.sh: line 6: [: 2-3: integer expression expected
Adresse gültig
$
War auch nur als einfaches Beispiel gedacht. Lässt sich natürlich beliebig erweitern.

Ich ging bei meinem Script davon aus, dass das erste Manöver (Extraktion mit Regex) bereits geglückt ist, und man das Ergebnis daraufhin weiteruntersuchen möchte.
Wenn das Umfeld stimmt (also IP-Adressen nett durch Leerzeichen getrennt sind, Klammern keine Rolle spielen etc.), und man nur "mal eben" testen will, ob einfache Randbedingungen stimmen, muss man nicht weiter in die Materie eintauchen.
Ansonsten geht es gleitend in das Thema "Parsen" über, und dann ist irgendwann auch mit Regexen das Ende der Fahnenstange erreicht.
Der Hauptunterschied zwischen etwas, was möglicherweise kaputtgehen könnte und etwas, was unmöglich kaputtgehen kann, besteht darin, dass sich bei allem, was unmöglich kaputtgehen kann, falls es doch kaputtgeht, normalerweise herausstellt, dass es unmöglich zerlegt oder repariert werden kann.
Douglas Adams

Antworten