FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: JoJota am 02 Dezember 2015, 15:41:13

Titel: Hilfe bei Regex gesucht
Beitrag von: JoJota am 02 Dezember 2015, 15:41:13
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
Titel: Antw:Hilfe bei Regex gesucht
Beitrag von: Elektrolurch am 02 Dezember 2015, 16:21:20
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  {
Titel: Antw:Hilfe bei Regex gesucht
Beitrag von: marvin78 am 02 Dezember 2015, 16:23:16
Ich empfehle diesen Lesestoff:

www.danielfett.de/internet-und-opensource,artikel,regulaere-ausdruecke
Titel: Antw:Hilfe bei Regex gesucht
Beitrag von: JoJota am 02 Dezember 2015, 17:21:34
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.
Titel: Antw:Hilfe bei Regex gesucht
Beitrag von: igami am 02 Dezember 2015, 19:41:37
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)) {
...
}
Titel: Antw:Hilfe bei Regex gesucht
Beitrag von: Prof. Dr. Peter Henning am 02 Dezember 2015, 19:54:17
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
Titel: Antw:Hilfe bei Regex gesucht
Beitrag von: JoJota am 02 Dezember 2015, 21:55:41
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 (http://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators) 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..  ::)
Titel: Antw:Hilfe bei Regex gesucht
Beitrag von: igami am 03 Dezember 2015, 06:01:53
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.
Titel: Antw:Hilfe bei Regex gesucht
Beitrag von: Prof. Dr. Peter Henning am 03 Dezember 2015, 08:11:01
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
Titel: Zitat:Antw:Hilfe bei Regex gesucht
Beitrag von: Elektrolurch am 03 Dezember 2015, 10:30:44
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
Titel: Antw:Hilfe bei Regex gesucht
Beitrag von: rudolfkoenig am 03 Dezember 2015, 16:10:43
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.
Titel: Antw:Hilfe bei Regex gesucht
Beitrag von: Elektrolurch am 04 Dezember 2015, 09:41:09
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.
Titel: Antw:Hilfe bei Regex gesucht
Beitrag von: Prof. Dr. Peter Henning am 04 Dezember 2015, 11:34:43
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
Titel: Antw:Hilfe bei Regex gesucht
Beitrag von: rudolfkoenig am 04 Dezember 2015, 11:51:50
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.