Hauptmenü

Hilfe bei Regex gesucht

Begonnen von JoJota, 02 Dezember 2015, 15:41:13

Vorheriges Thema - Nächstes Thema

JoJota

Hallo,

verzweifle gerade etwas mit der Regex Funktion in Perl. Alles mögliche schon ausprobiert, nichts hat geholfen.

my $eventDate = "05.12.2015";
my $reg = "(\d{2}).(\d{2}).(\d{4})";
if ($eventDate =~ $reg) {
Log(3,"Regex: Erfolgreich");
}
else {
Log(3,"Regex: Fehlgeschlagen");
}


Wo liegt der Fehler?

Gruß JoJota

Elektrolurch

Hallo,

mir kommt folgendes komisch vor:

if ($eventDate =~ $reg) {
würde ich schon mal so schreiben:
if ($eventDate =~m/$reg/)

Dann noch eins: ein "."ist ein beliebiges Zeichen in einer regex.
Wenn Du wirklich auf den "." hinaus willst, musst du ihn escapen also \. schreiben.


Elektrolurch

ein  {
configDB und Windows befreite Zone!

marvin78

Ich empfehle diesen Lesestoff:

www.danielfett.de/internet-und-opensource,artikel,regulaere-ausdruecke

JoJota

Hallo,
danke für die Antworten.

my $reg = "(\d{2})\.(\d{2})\.(\d{4})";
if ($eventDate =~m/$reg/) {


hat leider nichts am Ergebnis geändert. Den Punkt zu escapen hatte ich vergessen, ändert ja aber leider auch nichts am Ergebnis, da ein beliebiges Zeichen natürlich auch den Punkt als Zeichen mit einschließt.

Den Regex Befehl habe ich auch bereits mit regex101.com erfolgreich getestet, nur Perl nimmt ihn scheinbar nicht an.

igami

Wie wäre es mit einer Nebensub? Ich vermute das Problem liegt in der Auslagerung der Regex in eine Variable.

sub isDate($){
  return 1 if (shift =~ m/^(0[1-9]|(1-2)[0-9]|3[0-1])\.(0[0-9]|1[0-2])\.\d{4}$/);
}

if (isDate($eventDate)) {
...
}
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

Prof. Dr. Peter Henning

#5
1. Nein, die Auslagerung in eine Variable ist (prinzipiell) vollkommen OK

2. Zum Nachschlagen und Lernen besser: https://wiki.selfhtml.org/wiki/Perl/Regul%C3%A4re_Ausdr%C3%BCcke

LG

pah

JoJota

So, alles nochmal auseinander genommen, vorsichtig wieder zusammengesetzt, und mehrere Möglichkeiten durchprobiert. Lösung gefunden. Es hat doch an der Auslagerung gelegen.

Was funktioniert ohne Variable ist:

if ($eventDate =~ m/(\d{2}).(\d{2}).(\d{4})/) {

Mit Variable funktioniert folgendes Beispiel:


my $reg = qr"(\d{2}).(\d{2}).(\d{4})";
if ($eventDate =~ m/$reg/) {


Der String muss mithilfe von qr als Regex Quote markiert werden. So weit ich gesehen habe, wird das in keiner der verlinkten Nachschlagewerke erklärt. Da muss man erst mal drauf kommen..  ::)

igami

Na dann haben wir ja alle wieder was gelernt.

Dein $eventDate ist auch true, wenn am Anfang und/oder Ende noch etwas steht, dafür war bei mir ^ und $ mit drin.
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

Prof. Dr. Peter Henning

Sorry, aber das stimmt im Allgemeinen so nicht. Die Verwendung von qr() ist eine Möglichkeit, aber nicht zwingend.

Auszug aus dem seit Jahren stabil laufenden Code von 00_OWX.pm:

my $SER_regexp;
...
  $SER_regexp= "/dev/";
...
  if ($dev =~ m|$SER_regexp|i) { 


In dem vorliegenden Fall resultierte dass Nicht-Funktionieren der Auslagerung aus den "\d"-Substrings - die werden nämlich bei der lexikalischen Analyse nicht erkannt, denn \d ist kein Zeichen.

Das kann man übrigens sehr schön sehen, wenn man am Anfang seines Perl-.Moduls ein

use regex "debug"


einfügt.

LG

pah

Elektrolurch

Zitat:
1. Nein, die Auslagerung in eine Variable ist vollkommen OK

...LG

pah

War ja wohl nicht hilfreich, denn die Auslagerung in eine Variable war ja wohl wegen \d nicht ok.
Erst die Erklärung im Beitrag davor war hilfreich, aber leider nicht verständlich.
Für mich macht das keinen Unterschied, ob in einem m/ / Ausdruck eine direkte Konstante steht oder eine Variable. In beiden Fällen sollte der Inhalt wie eine regex interpretiert werden. Wäre das anders, so wäre das schon eine ziemliche Asymetrie in der Sprache.
Elektrolurch
configDB und Windows befreite Zone!

rudolfkoenig

Wenn man in der FHEM Kommandozeile
{ "(\d{2})\.(\d{2})\.(\d{4})" }
eingibt, dann merkt man das Problem schnell:
alle \ Zeichen werden bei der Zuweisung "verschluckt", und der Regex kriegt keins mehr. Abhilfe:
'(\d{2})\.(\d{2})\.(\d{4})'
oder
"(\\d{2})\\.(\\d{2})\\.(\\d{2})"


Das Problem hat also mit dem Regexp nur indirekt zu tun.

Elektrolurch

Ok. Jetzt verstehe ich es. Hätte mich auch gewundert, wenn perl da so asymetrisch gewesen wäre. Also war der obige Hinweis von PA definitiv falsch.
configDB und Windows befreite Zone!

Prof. Dr. Peter Henning

Sicher nicht.
ZitatIn dem vorliegenden Fall resultierte dass Nicht-Funktionieren der Auslagerung aus den "\d"-Substrings - die werden nämlich bei der lexikalischen Analyse nicht erkannt, denn \d ist kein Zeichen.

pah

rudolfkoenig

Herrschaften, bitte um Contenance.
Wer Recht hat, und wer nicht, bzw. wer wessen Formulierung nicht verstanden hat, ist mir im nachhinein egal. Wem das nicht egal ist, der soll das bitte privat klaeren, fuer sowas soll das Forum hier keine Buehne sein.