userReadings macht merkwürdige Dinge

Begonnen von Atouk, 25 Februar 2017, 04:22:46

Vorheriges Thema - Nächstes Thema

Atouk

...oder anders gesagt: Ich schaffe es irgendwie, mit "userReadings" erstaunliche Fehler zu produzieren.

Situation:
Ich habe einen TX25 (LaCrosse)-Sensor in einen Licht- und Regensensor umgebaut. Die Messwerte will ich von einer Pseudo-Temperatur [-40°C bis 60°C] in eine Prozentangabe umrechnen (also einfach 40 addieren).

Zwei Besonderheiten des TX25 sind,
- dass er zwei Temperaturwerte sendet, deren Readings fast gleich lauten: temperature bzw. temperature2
- dass er die beiden Werte nicht gleichzeitig, sondern abwechselnd alle 4 sek. sendet
Hinweis: "battery" habe ich - als derzeit einzige Beschränkung der Messwerte - mit einem event-min-interval auf 3600 sek. gesetzt.

Lösungsversuch:
Nach Forensuche sollte hierfür der Befehl "userReadings" geeignet sein. Der Eintrag hierzu in der Commmandref ist arg spartanisch, aber das meiste lernt man eh' mit Trial&Error, also einfach mal meine erste "Programmierung" in FHEM versucht:

attr Aussen2_LiRe userReadings temperature:.* { ReadingsVal("Aussen2_LiRe","temperature",-40)+40;; }

(Zuerst hatte ich beide Readings entsprechend korrigieren wollen, aber das Ergebnis war überhaupt nicht mehr transparent, also erstmal auf das erste Reading beschränkt)

Fehlerbilder:
a) temperature wird mehrfach (zweimal) um 40 erhöht
b) wenn dann ein "temperature2"-Reading kommt, wird temperature noch weitere zweimal um 40 erhöht (was ich im zweiten Schritt mit dem Zusatz :.* abzufangen versuchte, aber ohne Auswirkung)
c) Es wird jede Änderung des Wertes ins Log geschrieben - also auch der Originalwert, dann der geänderte Wert mit selben Timestamp. Damit wäre das Log für einen SVG-Plot nicht mehr verwendbar!

Log-Auszug mit Fehler:

2017-02-24_01:59:32 Aussen2_LiRe temperature: -32.2  <--- Fehler c)
2017-02-24_01:59:32 Aussen2_LiRe T: -32.2
2017-02-24_01:59:32 Aussen2_LiRe temperature: 7.8   
2017-02-24_01:59:32 Aussen2_LiRe temperature: 47.8   <--- Fehler a)

2017-02-24_01:59:37 Aussen2_LiRe temperature2: -12
2017-02-24_01:59:37 Aussen2_LiRe temperature: 87.8   <--- Fehler b) - userReadings dürfte m.E. nicht reagieren, wenn "temperature2" kommt
2017-02-24_01:59:37 Aussen2_LiRe temperature: 127.8  <--- (und dann auch wieder gleich zweimal..)

2017-02-24_01:59:41 Aussen2_LiRe temperature: -32.3
2017-02-24_01:59:41 Aussen2_LiRe T: -32.3
2017-02-24_01:59:41 Aussen2_LiRe temperature: 7.7
2017-02-24_01:59:41 Aussen2_LiRe temperature: 47.7

2017-02-24_01:59:46 Aussen2_LiRe temperature2: -11.8
2017-02-24_01:59:46 Aussen2_LiRe temperature: 87.7
2017-02-24_01:59:46 Aussen2_LiRe temperature: 127.7

(Leerzeilen für bessere Lesbarkeit eingefügt)

Zum Vergleich das Log, wenn das "attr .. userReadings" wieder gelöscht wurde:

2017-02-24_02:18:07 Aussen2_LiRe temperature: -32.3
2017-02-24_02:18:07 Aussen2_LiRe T: -32.3

2017-02-24_02:18:11 Aussen2_LiRe temperature2: -17.3

2017-02-24_02:18:16 Aussen2_LiRe temperature: -32.3
2017-02-24_02:18:16 Aussen2_LiRe T: -32.3

2017-02-24_02:18:20 Aussen2_LiRe temperature2: -17.2

2017-02-24_02:18:24 Aussen2_LiRe temperature: -32.5
2017-02-24_02:18:24 Aussen2_LiRe T: -32.5


Als Test habe ich entsprechendes Userreadings auf einem TX29DTH-LaCrosse gemacht (dieser liefert "temperature" und "humidity" immer gleichzeitig). Da hier positive Werte geliefert werden, habe ich diesmal 40 abgezogen:

attr LaCrosse_2D userReadings temperature:.* { ReadingsVal("LaCrosse_2D","temperature",-40)-40; }

Ergibt:

2017-02-25_01:00:02 LaCrosse_2D battery: ok
2017-02-25_01:00:02 LaCrosse_2D temperature: 20.7
2017-02-25_01:00:02 LaCrosse_2D humidity: 49
2017-02-25_01:00:02 LaCrosse_2D T: 20.7 H: 49
2017-02-25_01:00:02 LaCrosse_2D temperature: -19.3
2017-02-25_01:00:02 LaCrosse_2D temperature: -59.3

2017-02-25_01:00:11 LaCrosse_2D battery: ok
2017-02-25_01:00:11 LaCrosse_2D temperature: 20.7
2017-02-25_01:00:11 LaCrosse_2D humidity: 49
2017-02-25_01:00:11 LaCrosse_2D temperature: -19.3
2017-02-25_01:00:11 LaCrosse_2D temperature: -59.3

Ok, auch hier wird doppelt abgezogen. Das hat also noch nichts damit zu tun, dass im ersten Beispiel beide Readings sehr ähnlich lauten oder dass sie versetzt reinkommen.

Da andere mit den userReadings ja offenbar erfolgreich arbeiten (und da ich ein "update all" und einen "shutdown restart" auch als erstes probiert habe), scheine ich etwas eklatant falsch zu machen.

Nur was? Mit der commandref komme ich da leider nicht weiter  :(

Konkret:
- Wie kann ich verhindern, dass der Ursprungswert eingetragen wird? (Klar, irgendwie mit setreading und ggf. eigenem Logfile, aber das zu vermeiden sollte doch eigentlich genau der Sinn von userReadings sein?)
- Wie kann ich erreichen, dass "temperature" nicht auch triggert, wenn "temperature2" gesendet wird? (Mir scheint, dass in der RegExp zum Vergleich des Readings ein abschließender Test auf String-Ende, hier z.B. [:\s],  fehlt)

Danke und Gruß
Atouk

Icinger

#1
Du musst deinem UserReading einen anderen Namen als einem bereits bestehenden Reading geben.

Deine drei Fehlerbilder von oben sind alle gut erklärbar:
Fehlerbilder:
Zitata) temperature wird mehrfach (zweimal) um 40 erhöht
Sei froh, dass es nur zweimal war :)
Du schreibst ins reading "temperature" einen Wert, gleichzeitig will dein Userreading aber von ALLEN readings-änderungen benachrichtigt werden (.*)
Da beisst sich die Katze - äh FHEM - in den Schweif. Gottseidank unterbindet FHEM sowas
Zitatb) wenn dann ein "temperature2"-Reading kommt, wird temperature noch weitere zweimal um 40 erhöht (was ich im zweiten Schritt mit dem Zusatz :.* abzufangen versuchte, aber ohne Auswirkung)
Klar, dein Zusatz ".*" sagt FHEM ja erst, dass es auf alle readings reagieren soll. :)
Zitatc) Es wird jede Änderung des Wertes ins Log geschrieben - also auch der Originalwert, dann der geänderte Wert mit selben Timestamp.
Und auch das ist klar.
Das reading temperature wird vom Sensor befüllt und somit geloggt
     -> Dein Userreading "überschreibt" das selbige reading und wird somit auch geloggt

Lösung:
Was zB funktionieren wird:
attr Aussen2_LiRe userReadings tempProzent:temperature.* { ReadingsVal("Aussen2_LiRe","temperature",-40)+40;; }

Du musst einfach ein "neues" reading anlegen (tempProzent) und dieses nicht auf ALLE Änderungen innherhalb des devices reagieren lassen, sondern nur auf temperature.

lg, Stefan
Verwende deine Zeit nicht mit Erklärungen. Die Menschen hören (lesen) nur, was sie hören (lesen) wollen. (c) Paulo Coelho

dev0

userReadings ist dazu da ein NEUES Reading zu erstellen und nicht vorhandene anzupassen. Damit userReadings nicht von jedem Reading getriggert wird, muss man den optionalen Trigger angeben:

attr Aussen2_LiRe userReadings TEMPNEU:temperature:.* { ReadingsVal($NAME,"temperature",-40)+40;; }


Um Werte in Readings zu verändern kannst Du readingsChange verwenden.

Zitat von: Icinger am 25 Februar 2017, 07:00:48
Was zB funktionieren wird:
attr Aussen2_LiRe userReadings tempProzent:temperature.* { ReadingsVal("Aussen2_LiRe","temperature",-40)+40;; }

Das Beispiel ist mAn nicht korrekt, da "temperature.*" auf temperature und temperature2 triggert. Es fehlt der Doppelpunkt direkt nach dem Readingnamen.

Icinger

ZitatDas Beispiel ist mAn nicht korrekt, da "temperature.*" auf temperature und temperature2 triggert. Es fehlt der Doppelpunkt direkt nach dem Readingnamen.
Stimmt, den hatte ich vergessen, sorry.

lg, Stefan
Verwende deine Zeit nicht mit Erklärungen. Die Menschen hören (lesen) nur, was sie hören (lesen) wollen. (c) Paulo Coelho

Atouk

Wow, Samstag morgen um sieben nicht nur eine Antwort, sondern gleich eine ganze Diskussion - mann, schlaft Ihr denn nie? :)
Ich bin schwer beeindruckt, herzlichen Dank schonmal!

Ok, das mit dem "neues Reading erzeugen" statt das bestehende zu ändern habe ich jetzt verstanden. Folgendes habe ich also jetzt gemacht:

attr Aussen2_LiRe userReadings Licht:temperature:.* { ReadingsVal("Aussen2_LiRe","temperature",-40)+40; }

Ergebnis:

2017-02-25_22:32:36 Aussen2_LiRe temperature: -31.8
2017-02-25_22:32:36 Aussen2_LiRe T: -31.8
2017-02-25_22:32:36 Aussen2_LiRe Licht: 8.2
2017-02-25_22:32:36 Aussen2_LiRe Licht: 8.2
2017-02-25_22:33:07 Aussen2_LiRe temperature2: -38.1
2017-02-25_22:33:11 Aussen2_LiRe temperature: -31.8
2017-02-25_22:33:11 Aussen2_LiRe T: -31.8
2017-02-25_22:33:11 Aussen2_LiRe Licht: 8.2
2017-02-25_22:33:11 Aussen2_LiRe Licht: 8.2


Soweit jetzt schonmal prima. Allerdings werden die Werte immer noch doppelt eingetragen. Kann man das noch unterbinden (bzw. muss ich noch etwas verfeinern)?

Danke auch für den Tipp mit "readingsChange", muss ich auch mal mit spielen. Allerdings lese ich dazu:
after a Reading is set by a module, first the event-* attributes are evaluated, then userReadings, then stateFormat, then the readingsChange definitions (in alphabetical order), and after this the notifies, FileLogs, etc. again in alphabetical order.
- Als ich also bei meinem "Fehlversuch" mittels userReadings den Wert änderte, hätte er laut obiger Reihenfolge doch noch gar nicht (als Original) ins Filelog geschrieben werden dürfen, da das Filelog ja erst nach der Änderung bedient wurde?
- Wenn stateFormat vor readingsChange ausgeführt wird, dann müsste auf der Weboberfläche ein anderer Wert (nämlich der Originale) angezeigt werden als das, was ins Logfile geschrieben wird? Muss ich wohl mal ausprobieren...

(Klasse, eine Lösung, zwei neue Fragen. Ich glaube, man ist genau so lange ein absoluter Newbie, wie die Anzahl der neu entstehenden Fragen größer ist als die der erhaltenen Antworten...)


Nochmal zur commandref: Selbst jetzt fällt es mir noch schwer, den Kerngedanken "neues Reading ableiten statt bestehendes ändern" hier herauszulesen. Erschwerend kommt hinzu, dass ich die "Doppelpunkt-Relation" beim Notify als "Sensor:Messwert" kennengelernt habe. Bei userReadings wird der Doppelpunkt aber verwendet, um "künstlicher_Messwert" mit "Geräte_Messwert" zu verknüpfen. Der Sensor selbst wird gar nicht genannt - klar, denn auf den bezieht sich ja das gesamte Attribut. Puh.

Heute abend habe ich - dank Eurer Hilfe! - einen riesigen Schritt zum Verständnis der FHEM-Philosophie gemacht (man könnte auch sagen, ich fühle mich "entjungfert". Als "erleuchtet" würde ich mich noch nicht bezeichnen wollen, aber immerhin dämmert es langsam...  ;) )


Für andere Newbies: Eine ganz wesentliche Erkenntnis (die sich mir trotz längerem Schmökern in "Mit FHEM beginnen", commandref, Forum etc. bisher nicht einstellte), lautet:
Ob ein sensor ein wohlgeformtes "key:value"-Paar zurückliefert, also z.B. "temperature: 29°C", oder z.B. ein Schalter nur pauschal ein einfaches "on" (statt "state:on), hängt einzig vom Gerät (bzw. dem Modul, dass es auswertet) ab.

Der "Trigger" lautet also nie "gerät:eigenschaft:messwert", sondern "gerät:messwert-string". Da der Messwert-String so unterschiedlich aufgebaut sein kann, muss ich ihn für jeden Trigger gezielt auswerten.

Am konkreten Beispiel der LaCrosse-Sensoren kann ich also nicht einfach nur auf "temperature" triggern, weil es einfach keinen Messwert gibt, der nur dieses nackte Wort zurückgibt.
Stattdessen lautet der Messwert z.B. "temperature: 29.1°C", also triggere ich auf temperature:.*
(Der Doppelpunkt nach temperature ist wichtig, da er im Messwert-String vorkommt und hilft, von einem "temperature2" zu unterscheiden. Merke: bei temperature2 könnte ich den Doppelpunkt noch dahinterschreiben, muss es aber nicht mehr, da der String schon durch die 2 eindeutig wird).

So, das musste mal gesagt werden  :)

dev0

Zitat von: Atouk am 26 Februar 2017, 01:08:41
Soweit jetzt schonmal prima. Allerdings werden die Werte immer noch doppelt eingetragen. Kann man das noch unterbinden (bzw. muss ich noch etwas verfeinern)?
Das sollte so nicht sein, woher der doppelte Eintrag kommt ist mir im Moment nicht klar. Schau mal in den Eventmonitor, vielleicht hift das schon weiter.

Zitat
Danke auch für den Tipp mit "readingsChange"
...
Als ich also bei meinem "Fehlversuch" mittels userReadings den Wert änderte, hätte er laut obiger Reihenfolge doch noch gar nicht (als Original) ins Filelog geschrieben werden dürfen, da das Filelog ja erst nach der Änderung bedient wurde?
readingsChange und userReadings sind zwei verschiedene Sachen, du kannst nicht die Eigenschaften vermischen.

Zitat
Wenn stateFormat vor readingsChange ausgeführt wird,
Glaube ich nicht, habe es aber nicht geprüft.

Zitat
Erschwerend kommt hinzu, dass ich die "Doppelpunkt-Relation" beim Notify als "Sensor:Messwert" kennengelernt habe. Bei userReadings wird der Doppelpunkt aber verwendet, um "künstlicher_Messwert" mit "Geräte_Messwert" zu verknüpfen. Der Sensor selbst wird gar nicht genannt - klar, denn auf den bezieht sich ja das gesamte Attribut. Puh.
Das ist wohl historisch bedingt. Das Reading 'state' hat eine Sonderstellung, der Readingname wird in Events unterdrückt.
Wenn Du auf ein Event triggern möchtest, dann so: (auf das Leerzeichen achten)

device:reading: value


Wenn es um 'state' geht, dann so:

device:value


Das verhalten läßt sich aber auch mit dem Attribut addStateEvent anpassen.
In dem Zusammenhang mit Events kannst Du Dir auch schon mal Regular Expressions ansehen. zB. hier: https://wiki.selfhtml.org/wiki/Perl/Regul%C3%A4re_Ausdr%C3%BCcke

Zitat
Ob ein sensor ein wohlgeformtes "key:value"-Paar zurückliefert, also z.B. "temperature: 29°C", oder z.B. ein Schalter nur pauschal ein einfaches "on" (statt "state:on), hängt einzig vom Gerät (bzw. dem Modul, dass es auswertet) ab.
Das ist so nicht richtig. Es hägt davon ab ob es sich um 'state' oder um ein x-beliebiges anderes Reading handelt.

Atouk

#6
Ich habe das userReadings jetzt nochmal für den Testsensor reaktiviert. Im Event Monitor kommt dasselbe wie im Logfile. Sicherheitshalber habe ich auch nochmal einen shutdown restart gemacht (hätte ja etwas "krumm" sein können von meiner - ähem - regelwiedrigen Anwendung).
Coyp&Paste aus dem Event Monitor:
Zitat
2017-02-26 20:26:15 LaCrosse LaCrosse_2D battery: ok
2017-02-26 20:26:15 LaCrosse LaCrosse_2D temperature: 20.6
2017-02-26 20:26:15 LaCrosse LaCrosse_2D humidity: 50
2017-02-26 20:26:15 LaCrosse LaCrosse_2D mytemp: -19.4
2017-02-26 20:26:15 LaCrosse LaCrosse_2D mytemp: -19.4

Ist aber eh' für mich erstmal egal, da ich nach Euren Tipps gestern abend noch auf readingsChange umgestellt habe:

define chRegen readingsChange Aussen2_LiRe temperature (-?\d+\.?\d?) {$1 + 40.0}

Das funktioniert wunderbar (die RegExp habe ich so formuliert, damit auch eine Nachkommastelle berücksichtigt wird).
Und da ich auf alle "temperature" triggere, ändert es sowohl den Wert für die Helligkeit (temperature) als auch den für Regen (temperature2). Screenshot vom SVG-Plot hänge ich an.
Hmm, da es ein eigenes define und kein Attribut von Aussen2_LiRe ist, muss es wohl bei jedem Reading jedes Sensors geprüft werden - sprich, zuviele davon könnten irgendwann die Systemlast beeinflussen. Sollte man zumindest mal im Hinterkopf behalten.

Zitat
readingsChange und userReadings sind zwei verschiedene Sachen, du kannst nicht die Eigenschaften vermischen.
Schon klar. Aber hier wird ja nicht die Eigenschaft des Befehls beschrieben, sondern die allgemeine Reihenfolge der Verarbeitung, und die kommt ja übergreifend aus fhem.pl (oder einem modul).

Zitat
Zitat
    Wenn stateFormat vor readingsChange ausgeführt wird,
Glaube ich nicht, habe es aber nicht geprüft.
Glaube ich auch nicht, stand aber in der commandref (und wer wäre ich, zu an IHr zu zweifeln  ;) )

Habe mir meine Ausgabe also mal angesehen - das ist jetzt extrem merkwürdig. Zuerst mal - mein stateFormat lautet:
<B>temperature</B>% Helligkeit <B>temperature2</B>% Regen
(Sieht in den Interals zum Sensor etwas merkwürdig aus, da hier das <B> nicht interpretiert wird, aber auf der Geräte-Seite oben im DeviceOverview steht's wie gewünscht in Fett. Ist aber sicher wieder nicht nach Vorschrift :( ).

Ich erhalte:
-31% Helligkeit 2% Regen
Sobald ein neues temperature: - Reading (also der linke Wert) reinkommt, erhalte ich:
9% Helligkeit 2% Regen
Nach einem weiteren temperature-Reading wieder:
EDIT: Genauer nachgesehen: Sobald ein temperature2-Reading kommt, wird temperature auf den alten Wert zurückgesetzt (die Werte werden leider unregelmäßig empfangen, habe es erst verstanden, als ich parallel den Event Monitor offen hatte):
-31% Helligkeit 2% Regen

temperature (also Helligkeit) lasse ich übrigens mit "event-min-interval" alle 60 sek. durch, bei temperature2 (Regen) jeden Wert. Die Meldungen von "temperature2" ändern die Anzeige vom linken Wert nicht. Der linke Wert springt folglich ca. alle 60 sek. um.
Zur Erinnerung: temperature und temperature2 kommen NIE in einem Reading gleichzeitig. Vielleicht hat es irgendwas damit zu tun...
Ergänzend: Ich hatte im stateFormat probeweise "temperature:" geschrieben, um sicherzustellen, dass es nicht mit "temperature2" durcheinanderkommt. Leider wurde das ":" nicht mitinterpretiert, so dass im DeviceOverview zu lesen war:
9.3:% Helligkeit 2% Regen
(Also ":" vor dem ersten %)

Hier könnte eine Fehlerquelle bei der internen Interpretation liegen, aber ich wüsste nicht, wie das beobachtete Verhalten damit zu erklären wäre, da der erste Wert ja nicht nach 4 sek (beim ersten temperature2) zurückspringt, sondern erst beim neuen "temperature:".
EDIT: Ok, das Problem tritt auf, wenn nur ein Reading des Inhalts "temperature2" kommt. readingsChange ändert also auch den Wert für "temperature", obwohl das gar nicht im aktuellen Reading geliefert wird. Und offenbar nimmt es den Wert aus einer Art internem Backup - wendet dann aber die RegExp hierauf nicht an (wahrscheinlich, weil für "temperature" ja kein Wert kam, den es korrigieren könnte).
Aus meiner Sicht dürfte readingsChange den Fehler haben, dass es nicht berücksichtigt, dass verschiedene Readings zu verschiedenen Zeiten kommen können.

Andererseits: meine naiven Annahmen wurden schon mehrfach mit dem Hinweis einer komplexeren Design-Philosophie wiederlegt... (der Pfad zur Erleuchtung ist ein steiniger! :) )

Zitat
Wenn Du auf ein Event triggern möchtest, dann so: (auf das Leerzeichen achten)
[--]
... und ich dachte, ich hätte es verstanden. Seufz.

Mal langsam! Schauen wir uns mal die Definition von "notify" an. Syntax:
define <name> notify <Suchmuster> <Anweisung>

Wenn ich da ein Leerzeichen im Suchmuster mache, müsste das gesuchte Reading doch als <Anweisung> interpretiert werden? Sprich: wenn vor dem Leerzeichen ein Doppelpunkt steht, dann ist es gar kein Leerzeichen im Sinne der obigen Syntax, sondern sagt FHEM, dass der Teil nach dem Leerzeichen noch zum Event (Suchmuster) gehört?!
... Ihr macht's Euren Verfolgern aber auch nicht grad leicht, gell?  ::)  ;)
(Passt irgendwie zur allgemeinen Philosophie von Perl, die "Unlesbarkeit by Design" zumindest ermöglicht...)

Zitat
In dem Zusammenhang mit Events kannst Du Dir auch schon mal Regular Expressions ansehen.

Danke für den sehr netten Hinweis - allerdings scripte ich in Perl (sporadisch) seit gut zwei Dekaden, und träume inzwischen schon fast akzentfrei von/in RegExp's..  8)
(Als ich erfuhr, dass FHEM in Perl realisiert ist, war ich direkt begeistert).

Icinger

Guten Morgen,

ZitatHmm, da es ein eigenes define und kein Attribut von Aussen2_LiRe ist
Deshalb bin ich eher beim UserReading denn bei ReadingsChange :D

Du kannst doch die regEx für temperature einfach genauer definieren:
attr Aussen2_LiRe userReadings TEMPNEU:temperature\:\s.* { ReadingsVal($NAME,"temperature",-40)+40;; }

lg, Stefan
Verwende deine Zeit nicht mit Erklärungen. Die Menschen hören (lesen) nur, was sie hören (lesen) wollen. (c) Paulo Coelho

dev0

Zitat von: Atouk am 26 Februar 2017, 21:46:05
Wenn ich da ein Leerzeichen im Suchmuster mache

Das war anders gemeint: Du sollst kein Leerzeichen "machen", sondern es in Deiner regex berücksichtigen, damit die regex matcht.

Atouk

#9
Zitat von: Icinger am 27 Februar 2017, 05:46:57
Du kannst doch die regEx für temperature einfach genauer definieren:
attr Aussen2_LiRe userReadings TEMPNEU:temperature\:\s.* { ReadingsVal($NAME,"temperature",-40)+40;; }

Gute Idee, den Doppelpunkt auch zu "escapen" - selsbt wenn er in der RegExp kein Sonderzeichen darstellt.
Berücksichtigt FHEM, ob ein Zeichen "escaped" ist, um den Teilstring für die RegExp (Trigger) zu bestimmen, sprich: würde ein escaptes Leerzeichen genauso funktionieren wie das \s?

Atouk

Zitat von: dev0 am 27 Februar 2017, 08:18:46
Das war anders gemeint: Du sollst kein Leerzeichen "machen", sondern es in Deiner regex berücksichtigen, damit die regex matcht.
Ach so, Du meintest es so, wie Icinger beschrieben hat - sorry, ich stand wohl auf dem Schlauch.

Ok, danke nochmal für die Hilfe! Ich denke, für die nächsten Anwendungsfälle bin ich jetzt einigermaßen vorbereitet.