Ankündigung

Einklappen
Keine Ankündigung bisher.

items.match_items() wirklich RegEx fähig?

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    items.match_items() wirklich RegEx fähig?

    Hi,

    ich versuche gerade alle Items zurück liefern zu lassen, die mit Pfad X anfangen und auf * enden, aber nicht deren Subitems.
    Dazu habe ich mal Beispielhaft folgende RegEx gebaut: ^eg.flur.licht(\w|\d)*(?<!\.1)$

    Hier mal ein paar Beispiel Item Namen:
    eg.flur.licht1.stromwert
    eg.flur.licht1.wh
    eg.flur.licht1.wh_reset
    eg.flur.licht1.betriebsstunden
    eg.flur.licht1.betriebsstunden_reset
    eg.flur.licht1
    eg.flur.licht2.stromwert
    eg.flur.licht2
    eg.flur.licht_vrr.online
    eg.flur.licht_vrr
    eg.flur.licht
    eg.flur.licht.wh

    Aber trotzdem bekomme ich von match_items() alle Child-Items zurück geliefert. Im Online RegExr bekommm ich nur die gewünschten Items eg.flur.licht1 / eg.flur.licht2 / eg.flur.licht

    https://regexr.com/5tsju
    Hat wer ne Idee was ich falsch mache, oder geht das einfach nicht? Bin halt auch wirklich nicht der RegEx Guru

    Gruß,
    Thomas
    Zuletzt geändert von TCr82; 27.05.2021, 23:35.

    #2
    Ein flüchtiger Blick in den Quellcode zeigt
    Code:
     regex = regex.replace('.', '\.').replace('*', '.*') + '$'
    Das sorgt unter anderem dafür, das Dein \. zu einem \\. werden dürfte und aus * ein .* wird. Inwieweit das bei der Auswertung eine Rolle spielt müßtest Du selbst testen.
    Richtig wäre es denn man nur aus einem . ohne vorherigen \ einen \. machen würde. Das scheint mir aber nicht rückwärtskompatibel zu sein.
    Vielleicht wäre ein Warnung an dieser Stelle für's logging angebracht.

    Ob das $$ was dann am Ende entsteht schädlich ist, weiß ich auch nicht.

    Bin gespannt auf die Ergebisse Deiner weiteren Tests. Du kannst ja auch ein wenig Logikcode schreiben um das zu testen oder alternativ das Executor Plugin bemühen.

    Kommentar


      #3
      Mal unabhängig davon die Frage, was die Regex-Ersetzung im Code soll. Sollen Wildcards (*) emuliert werden?

      Ich fände es konsistent, wenn man entweder von Wildcards (*, ?) spricht oder von Regex, dann aber bitte auch "richtige" Regex. Möglicherweise gäbe es eine Möglichkeit, beide zu nutzen. Von Regex zu sprechen und sie dann "kaputt zu machen", finde ich seltsam.

      (Und ja, ich weiß, dass Regex gerade Neulinge schnell überfordern können, aber dann sollte man nicht von Regex sprechen)

      Kommentar


        #4
        Sollen Wildcards (*) emuliert werden?
        Da müßtest Du den Original Ersteller der Software Fragen. Das ist eine Altlast aus Smarthome.py Zeiten, siehe Github vom 3. November 2014.
        Wenn Dir dazu was einfällt kannst Du die Implementation ja erweitern.

        PS: Ich bin da vor Jahren auch mal drüber gestolpert...

        Kommentar


          #5
          Vermutlich bin ich da ja auch hier
          https://knx-user-forum.de/forum/supp...tch_item-regex
          drüber gestolpert. Das ist auch Wildcard und kein RegEx...
          Derzeit zwischen Kistenauspacken und Garten anlegen.
          Baublog im Profil.

          Kommentar


            #6
            Unter der Vorbedingung das in lib.item.items.py die Funktion match_items() leicht korrigiert wird (siehe Post #2):

            Code:
                def match_items(self, regex, compat=False):
                    #...
                    regex, __, attr = regex.partition(':')
                    if not compat:
                        regex = regex.replace('.', '\.').replace('*', '.*') + '$'
            
                    regex = re.compile(regex)
                    #...
            Erzeugt folgender Python Code im Executor Plugin:

            Code:
            from lib.item import Items
            sh_items = Items.get_instance()
            
            mex = "^eg.flur.licht(\w|\d)*(?<!\.1)$"
            print(f'Ein RegEx "{mex}" ergibt:')
            print(40*'-')
            for i in sh_items.match_items(mex):
                print(i)
            print(40*'=')
            diese Ausgabe:

            Code:
            Ein RegEx "^eg.flur.licht(\w|\d)*(?<!\.1)$" ergibt:
            ----------------------------------------
            eg.flur.licht1.stromwert.wh
            eg.flur.licht1.stromwert.wh_reset
            eg.flur.licht1.stromwert.betriebsstunden
            eg.flur.licht1.stromwert.betriebsstunden_reset
            eg.flur.licht1.stromwert
            eg.flur.licht1
            eg.flur.licht2.stromwert
            eg.flur.licht2
            eg.flur.licht_vrr.online
            eg.flur.licht_vrr
            ========================================
            Ändert man den Python Code im Executor leicht ab in dem man noch ein True beim Aufruf spendiert, liefert

            Code:
            from lib.item import Items
            sh_items = Items.get_instance()
            
            mex = "^eg.flur.licht(\w|\d)*(?<!\.1)$"
            print(f'Ein RegEx "{mex}" ergibt:')
            print(40*'-')
            for i in sh_items.match_items(mex,True):
                print(i)
            print(40*'=')
            dann diese Ausgabe im Executor Plugin:

            Code:
            Ein RegEx "^eg.flur.licht(\w|\d)*(?<!\.1)$" ergibt:
            ----------------------------------------
            eg.flur.licht1
            eg.flur.licht2
            eg.flur.licht_vrr
            eg.flur.licht
            ========================================
            Ist das das, was Du auch erwartet hast?

            Kommentar


              #7
              hey ja, also letzteres - das ist es
              danke
              Zuletzt geändert von TCr82; 29.05.2021, 14:53.

              Kommentar


                #8
                Zuletzt war Msinn da beim Refactoring dran. Es gibt auch noch eine Funktion des smarthome Objektes die als deprecated markiert ist. Blöderweise müßte man das dann entweder auch ändern oder rauswerfen.
                TCr82 für Dich mag das oben erstmal so gut gehen. Ich möchte aber ungerne das einfach so in develop einpflegen.

                Kommentar


                  #9
                  schade, aber vielleicht denkt Msinn da ja vielleicht dran, das so oder so ähnlich mit einzubauen.

                  Habe es jetzt mal temporär so bei mir eingebaut, damit ich mit meinem Spracherkennungs-Projekt weiter komme.

                  Kommentar


                    #10
                    Das Problem ist, dass das ein breaking change ist - auch wenn ich nicht weiß, wie viele Leute das benutzen.

                    Es wäre denkbar, zur nächsten Major oder so die aktuelle Funktion umzubenennen (statt regex z.B. find) und die o.a. regex-Änderung dann als regex einzubauen. Dann könnte jeder die Suchgrammatik nutzen, die ihm besser passt.

                    Dann sollte man das aber an allen Stellen analog anpassen, wo find/regex/... verwendet wird.

                    Die Python-Regex-Implementation ist eine eigene? oder PCRE?

                    Kommentar


                      #11
                      Ich wäre auch dafür das in 2 Funktionen zu implementieren. Einmal das alte Verhalten und ein mal regex.

                      Evtl. könnte man das Ganze so gestalten, dass es für Nutzer anpassungsfreundlicher wird und auch nicht bis zu einem Major Release warten muss. (Eine v2.0 sehe ich im Moment noch nicht am Horizont.)

                      Meine Idee:
                      • Eine neue Funktion mit regex Funktionalität, die einen neuen Namen bekommt
                      • Die bisherige Funktion mit einem weiteren neuen Namen versehen
                      • Unter dem bisherigen Funktionsnamen eine Funktion schreiben, die die bisherige Funktion (unter dem neuen Namen) aufruft.
                      • den bisherigen Funktionsnamen in der Doku für deprecated erklären
                      Das würde Nutzern eine weiche Umstellung über die nächsten Releases ermöglichen.
                      Zuletzt geändert von Msinn; 31.05.2021, 17:28.
                      Viele Grüße
                      Martin

                      There is no cloud. It's only someone else's computer.

                      Kommentar


                        #12

                        Kommentar

                        Lädt...
                        X