FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: andies am 19 Mai 2019, 22:14:59

Titel: [beantwortet] Perlfrage zu split und Regex
Beitrag von: andies am 19 Mai 2019, 22:14:59
Ich habe ein Modul, in dem Dinge passieren, die nicht passieren sollen. Mein Problem besteht in folgendem Stück Code:

$buf =~ s/([\r]?[\n]?vctrld>[\r]?[\n]?)*//;
...
my @zeilen = split /\n/, $buf;
my $zeilen = @zeilen;


Zur Erläuterung: Aus einer externen Quelle kommt $buf, das normalerweise genau eine oder genau vier Zeilen enthält. Dieser $buf enthält (manchmal) den Prompt vctrld>, der mit oben genanntem Code entfernt wird. Danach wird $buf zeilenweise zerlegt, wobei die Anzahl der Zeilen in $zeilen steht. Danach wird ausgewertet, wie viele Zeilen es gab und was in denen steht.

Es kommt nun mehrfach vor, dass $buf anscheinend so etwas wie ,,45\nvctrld>" enthält. Ich bekomme nämlich in der Auswertung gesagt, dass zwei Zeilen vorliegen, und ich lasse mir die auch anzeigen. Das ergibt dann eine (vermeidbare) Fehlermeldung.

Meine Frage: Ich kriege diese Fehlermeldung nicht in den Griff. Weder chomp($buf) noch der regex

$buf =~ s/([\r]?[\n]?vctrld>[\r]?[\n]?)*//;
$buf =~ s/\n$//;   # <=== NEU
...

löschen den Zeilenvorschub am Ende, nachdem vcontrold entfernt wurde. Vermutlich verstehe ich hier etwas grundsätzliches nicht. Kann mir da jemand helfen?


Also ich lasse mir jetzt mal die raw buf anzeigen und schaue dann mal, wo genau das Problem auftritt. Dann werde ich sicher sehen, wie das zu lösen ist. Man muss immer beim Urschleim anfangen.
Titel: Antw:[beantwortet] Perlfrage zu split und Regex
Beitrag von: andies am 20 Mai 2019, 06:14:03
So, jetzt kann ich endlich meine Frage präzisieren. Ich empfange folgenden raw-Einträge in $buf
2019.05.20 00:06:43 1: Viessmann raw $buf = vctrld>
2019.05.20 00:06:44 1: Viessmann raw $buf = 23.600000 Grad\n
2019.05.20 00:06:44 1: Viessmann raw $buf = vctrld>
2019.05.20 00:06:45 1: Viessmann raw $buf = 16.100000 Grad\n

(\n von mir hinzugefügt, sonst sieht man das im Log nicht). Diese können ausgewertet werden. Ab und an kommt es aber vor, dass da erscheint

2019.05.20 00:37:04 1: Viessmann raw $buf = vctrld>
2019.05.20 00:37:08 1: Viessmann raw $buf = 23.600000 Grad\nvctrld>

und der "Zusatz" \nvctrld> führt dann zu einer Fehlermeldung. Der muss also raus. Ich dachte, ich schaffe das mit folgendem Code und das ist nicht der Fall:

$buf =~ s/([\r]?[\n]?vctrld>[\r]?[\n]?)*//;

Warum? Der Regex sollte doch in 23.600000 Grad\nvctrld den entsprechenden String am Ende erkennen und löschen?
Titel: Antw:[beantwortet] Perlfrage zu split und Regex
Beitrag von: andies am 20 Mai 2019, 06:22:48
Ich glaube, ich habe es. "?" ist nicht nur "null mal oder ein Mal", sondern das ist auch "lazy regex", siehe https://www.rexegg.com/regex-quantifiers.html (https://www.rexegg.com/regex-quantifiers.html). Und dann lässt er den Zeilenumbruch weg, den er erfassen soll: Weil dem Regex vctrold> reicht und er sich nicht um das vorangestellte [\n]? kümmert. "Reicht ja." Wenn ich die Lösung habe, melde ich mich.

(Manchmal kommt mir das wie ein Selbstgesprächsforum vor.  8) )
Titel: Antw:[beantwortet] Perlfrage zu split und Regex
Beitrag von: andies am 20 Mai 2019, 21:19:23
Also jetzt brauche ich doch Hilfe. Ich habe folgenden Code

...
$buf =~ s/vctrld>//;
$buf =~ s/\n$//;
...
$buf =~ s/\n/<newline>/;
Log3 $name, 1, $name.": Cannot handle buf = ".$buf;
...

und jetzt frage ich mich, wieso da überhaupt Zeilenvorschübe am Ende auftauchen können, wie man an folgendem Logeintrag sieht
2019.05.20 20:02:51 1: Viessmann: Cannot handle buf = 41.299999 Grad<newline>vctrld>
Das geht doch logisch gar nicht?!
Titel: Antw:[beantwortet] Perlfrage zu split und Regex
Beitrag von: t1me2die am 21 Mai 2019, 11:06:07
Hi Andi,

verstehe ich es richtig, dass du Probleme mit den Zeilenumbrüchen und mit den Prompt's hast?

Ersetze doch im ersten Step im $buf einfach alle Umbrüche...
$text =~ s/\n|\r//g;

Genauso würde ich auch die Prompt's entfernen (vctrld>).

Gruß
Mathze
Titel: Antw:[beantwortet] Perlfrage zu split und Regex
Beitrag von: DeeSPe am 21 Mai 2019, 11:17:51
Oder sowas:

$buf =~ s/\r//g;
my @zeilen;
foreach (split /\n/,$buf)
{
  $_ =~ s/vctrld>//g;
  push @zeilen,$_;
}


Damit solltest Du in @zeilen alle Zeilen haben ohne Umbrüche und ohne Prompts.

Gruß
Dan
Titel: Antw:[beantwortet] Perlfrage zu split und Regex
Beitrag von: andies am 21 Mai 2019, 18:52:37
Danke, das mache ich mal. Denn ich habe manchmal Rückmeldungen, die über vier Zeilen gehen - und dann kann ich nicht ohne Weiteres die \n entfernen, die müssen da nämlich enthalten sein.
Titel: Antw:[beantwortet] Perlfrage zu split und Regex
Beitrag von: andies am 22 Mai 2019, 07:18:38
Ich hatte jetzt 24h keine Probleme, sonst wären da bis zu zehn Macken. Fall gelöst.


Gesendet von iPhone mit Tapatalk Pro
Titel: Antw:[beantwortet] Perlfrage zu split und Regex
Beitrag von: DeeSPe am 22 Mai 2019, 08:10:23
Zitat von: andies am 22 Mai 2019, 07:18:38
Ich hatte jetzt 24h keine Probleme, sonst wären da bis zu zehn Macken. Fall gelöst.

Schön, sagst Du uns noch was nun Deine finale Lösung ist?

Gruß
Dan
Titel: Antw:[beantwortet] Perlfrage zu split und Regex
Beitrag von: andies am 22 Mai 2019, 08:57:34
Eine Mischung aus den vorherigen Vorschlägen. Dein Code hat mir am besten gefallen, ging aber nur mit zu viel Aufwand: Bei mir sind Empfang und Verarbeitung von $buf getrennt und das hätte ich dann umsortieren müssen, da war ich einfach zu faul.

#remove prompt and trailing empty lines, auch https://forum.fhem.de/index.php?topic=100698
$buf =~ s/\r//g;
$buf =~ s/vctrld>//g;
$buf =~ s/\n$//;