FHEM Forum

FHEM - Entwicklung => FHEM Development => Thema gestartet von: DeeSPe am 25 März 2021, 10:52:12

Titel: Funktion für RegEx Escape?
Beitrag von: DeeSPe am 25 März 2021, 10:52:12
Hallo liebe Programmierer,

gibt es in FHEM bereits eine Funktion um vorgegebene Strings zu escapen dass sie RegEx konform sind, ähnlich zu SemicolonEscape?
Meine Aufgabenstellung lautet ein Array mit Kalender-Events zu befüllen, aber keine doppelten Einträge zu haben. Dazu vergleiche ich per RegEx ob es den Eintrag im Array schon gibt:
push @events,$evt if (!grep /^$evt$/,@events);
Das Problem was sich nun hier (https://forum.fhem.de/index.php/topic,64317.msg1142819.html#msg1142819) gezeigt hat ist, dass im Kalender auch Sonderzeichen wie "?" stehen können und diese in RegEx eine bestimmte Bedeutung haben. Somit kommt es an der Stelle zum Crash.

Wenn es noch keine solche Funktion in FHEM gibt, macht es Sinn eine solche zu integrieren? Oder gibt es andere Möglichkeiten das zu umgehen? Wie handhabt ihr soetwas wenn man den vorgegebenen String selbst nicht unter Kontrolle hat?

Danke.

Gruß
Dan
Titel: Antw:Funktion für RegEx Escape?
Beitrag von: rudolfkoenig am 25 März 2021, 11:22:48
CheckRegexp($regexp, $context) prueft, ob ein Regexp zum Perl-Absturz fuehrt.

Eine Funktion, nachdem Du fragst, kenne ich nicht.
Wenn ich etwas nicht als Regexp pruefen will, dann pruefe ich es mit eq/ne.
Vermutlich denke ich aber zu einfach.
Titel: Antw:Funktion für RegEx Escape?
Beitrag von: DeeSPe am 26 März 2021, 14:49:07
Danke Rudi!
Die Funktion war mir bisher nicht aufgefallen.
Allerdings bringt sie mich in diesem Falle auch nicht wirklich weiter.

Wie könnte man denn mit "eg", statt meiner Version oben, das hinzuzufügende Element vorher prüfen ob es das selbe schon im Array gibt?
Kann mir da jemand bitte mal einen Denkanstoß geben?

Gruß
Dan
Titel: Antw:Funktion für RegEx Escape?
Beitrag von: Beta-User am 26 März 2021, 15:07:04
Weiß nicht, ob das weiterhilft, aber m.E. ist das hier in die Richtung "eq/ne", die Rudi angedeutet hat - die Array-Elemente werden dabei einfach als Label für einen Hash verwendet:

sub get_unique {
    my $arr    = shift;
    my $sorted = shift; #true if shall be sorted (longest first!)
   
    my %seen;
   
    #method 2 from https://stackoverflow.com/a/43873983
    my @unique = grep {!$seen{$_}++} @{$arr}; #we may need to sort, see https://stackoverflow.com/a/30448251
   
    return if !@unique;

    return @unique if !$sorted;

    my @sorted = sort { length($b) <=> length($a) } @unique;
    #Log3(undef, 5, "get_unique sorted to ".join q{ }, @sorted);
    return @sorted;
}


Übergeben wird die Referenz auf ein Array, sowie (optional) die Info, ob der Länge nach sortiert werden soll (längster string zuerst), z.B. so wie hier:
sub RHASSPY_allRhasspyNames {
    my $hash = shift // return;

    my @devices;

    return if !defined $hash->{helper}{devicemap};
    my $rRooms = $hash->{helper}{devicemap}{rhasspyRooms};
    for my $key (keys %{$rRooms}) {
        push @devices, keys %{$rRooms->{$key}};
    }
    return get_unique(\@devices, 1 );
}

(Stammt aus dem aktuellen Code von RHASSPY).
Titel: Antw:Funktion für RegEx Escape?
Beitrag von: rudolfkoenig am 26 März 2021, 15:18:30
push @events,$evt if (!grep { $_ eq $evt  },@events);

(ungetestet)
Titel: Antw:Funktion für RegEx Escape?
Beitrag von: CoolTux am 26 März 2021, 16:26:05
Zitat von: rudolfkoenig am 26 März 2021, 15:18:30
push @events,$evt if (!grep { $_ eq $evt  },@events);

(ungetestet)

Ich bilde mir ein das es ohne Komma vor @events sein muss

push @events,$evt if (!grep { $_ eq $evt  } @events);


leider ebenfalls ungetestet.


Grüße
Titel: Antw:Funktion für RegEx Escape?
Beitrag von: DeeSPe am 27 März 2021, 10:23:53
Vielen Dank für Eure geteilten Lösungsansätze.
Ich komme leider erst nächste Woche dazu die Codeschnipsel zu testen, werde aber definitiv berichten ob ich damit Erfolg erziele.

Gruß
Dan
Titel: Antw:Funktion für RegEx Escape?
Beitrag von: Christoph Morrison am 27 März 2021, 11:24:39
https://perldoc.perl.org/List::Util#uniq (https://perldoc.perl.org/List::Util#uniq) (List::Util ist ein Core-Module und immer bei Perl dabei)
Titel: Antw:Funktion für RegEx Escape?
Beitrag von: DeeSPe am 09 Februar 2023, 22:37:13
Ist ja echt schon ewig her dass ich hier eine Rückmeldung geben wollte.
Habe heute erst einmal testweise den Vorschlag von Rudi/Marko umgesetzt. Das hat soweit ich es beurteilen kann gut geklappt.

Dann habe ich auch den Vorschlag von Christoph umgesetzt und muss sagen dass mit dieser noch besser gefällt.
Habe jetzt jedes grep rausgeworfen bei dem ich das Vorhandensein eines Elements im Array geprüft habe und dann nur vor Weitergabe des Array dieses mittel 'uniq' verschlankt.
Ich denke diese Lösung dürfte etwas performanter sein als im Loop immer wieder mit grep zu prüfen ob das Element schon vorhanden ist.

Danke nochmal an alle Beteiligten, auch wenn es lange gedauert hat bis ich das umgesetzt habe.

Gruß
Dan