Perl Zeichenkette in Zeichenkette einsetzten

Begonnen von EnderPhilipp, 26 Januar 2017, 06:59:33

Vorheriges Thema - Nächstes Thema

EnderPhilipp

Hi Liebe FHEM-Community,  ;D

ich habe den Mensaplan meiner Schule per HTTPMOD in FHEM integriert. (Danke JoWiemann)

In "Rohform" sehen die Readings so aus:
Nudelauflauf mit Tomaten und Käse überbacken | Chinakohlsalat | Apfelmus | G A1

Das habe ich zu dem hier verbessert:
Nudelauflauf mit Tomaten und Käse überbacken | Chinakohlsalat | und als Nachtisch Apfelmus

Jetzt würde ich gerne, dass das am Ende so aussieht:
Nudelauflauf mit Tomaten und Käse überbacken | mit Chinakohlsalat | und als Nachtisch Apfelmus

Das würde ich selber wahrscheinlich auch hinkriegen, aber manchmal steht da schon in der "Rohform" ein mit:
Klopse "Königsberger Art" | mit Kartoffelpüree und Karotten in Butter | Himbeerjoghurt | G A1 C


Deshalb meine Frage:
Wie kann ich prüfen, ob hinter den ersten 5 Zeichen nach dem ersten | schon ein mit oder ein und steht ????

Mfg
Philipp  ;D
¡¡¡ANFÄNGERALARM!!!
Raspberry Pi 3 (Hauptsystem)
Raspberry Pi B+ (Kellersonde)
Homematic,Philips Hue, LD382, nanoCul 433/868mhz, MPD, Intertechno, FIRMATA, EspEasy, SSCAM, STV, HDMI-CEC, EchoDot

betateilchen

#1
Zitat von: EnderPhilipp am 26 Januar 2017, 06:59:33
Wie kann ich prüfen, ob hinter den ersten 5 Zeichen nach dem ersten | schon ein mit oder ein und steht ????

Zerlege die Zeichenkette an den | in ihre Bestandteile,


my @m = split("|",<text>);


Entferne per regexp die gewünschten Teile (egal ob sie vorhanden sind oder nicht)


$m[1] =~ s/^mit//i;
$m[1] =~ s/^und//i;


Danach hast Du einen klar definierten Zustand:


[0] = Klopse Königsberger Art
[1] = Kartoffelpüree und Karotten in Butter
[2] = Himbeerjoghurt (igitt)
[3] = G A1 C


und kannst den kompletten String einfach wieder so zusammensetzen, wie Du ihn brauchst.


return "$m[0] mit $m[1] und als Nachtisch $m[2] | $m[3]";


Hoffe, das Prinzip ist klargeworden.

(ich weiß, dass es auch noch einfacher geht, aber das wäre schwieriger, es verständlich zu erklären)
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

EnderPhilipp

#2
Danke, werde ich später mal testen.

Nur eine kleine Frage zu
$menue[1] =~ s/^mit//i;

Woher "weiß" die Suchfunktion wo sie suchen muss ????

Und warum wird das "und" zwischen Kartoffelpüree und Karotten nicht ersetzt?


Mit freundlichen Grüßen
Philipp ;D
¡¡¡ANFÄNGERALARM!!!
Raspberry Pi 3 (Hauptsystem)
Raspberry Pi B+ (Kellersonde)
Homematic,Philips Hue, LD382, nanoCul 433/868mhz, MPD, Intertechno, FIRMATA, EspEasy, SSCAM, STV, HDMI-CEC, EchoDot

betateilchen

Zitat von: EnderPhilipp am 26 Januar 2017, 08:05:06
Woher "weiß" die Suchfunktion wo sie suchen muss ????

weil da $m[1] steht (das "$menue" war ein tippfehler von mir)

Zitat von: EnderPhilipp am 26 Januar 2017, 08:05:06
Und warum wird das "und" zwischen Kartoffelpüree und Karotten nicht ersetzt?

weil die regexp mit ^ angegeben ist, was bedeutet "wenn am Anfang 'mit' steht".


Weitere Infos zu regular expressions findest Du massenhaft im Internet.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

EnderPhilipp


Mein jetziger Code
my $mensamorgen = ReadingsVal("Mensa", "Donnerstag", "");
my @m = split("|",<text>);
$m[1] =~ s/^mit//i;
$m[1] =~ s/^und//i;
my $tomorrow = "$m[0] mit $m[1] und als Nachtisch $m[2] | $m[3]";
fhem("setreading Mensa Morgen $tomorrow");


Als Ergebnis kommt:

mit und als Nachtisch |


Wie kann ich split() "sagen", dass es $mensamorgen zerteilen soll ?

Mfg
Philipp
¡¡¡ANFÄNGERALARM!!!
Raspberry Pi 3 (Hauptsystem)
Raspberry Pi B+ (Kellersonde)
Homematic,Philips Hue, LD382, nanoCul 433/868mhz, MPD, Intertechno, FIRMATA, EspEasy, SSCAM, STV, HDMI-CEC, EchoDot

DeeSPe

Zitat von: EnderPhilipp am 26 Januar 2017, 16:21:41
Mein jetziger Code
my $mensamorgen = ReadingsVal("Mensa", "Donnerstag", "");
my @m = split("|",<text>);
$m[1] =~ s/^mit//i;
$m[1] =~ s/^und//i;
my $tomorrow = "$m[0] mit $m[1] und als Nachtisch $m[2] | $m[3]";
fhem("setreading Mensa Morgen $tomorrow");


Als Ergebnis kommt:

mit und als Nachtisch |


Wie kann ich split() "sagen", dass es $mensamorgen zerteilen soll ?

Mfg
Philipp

So wie man split immer benutzt:
my @m = split("|",$mensamorgen);

Dieses Beispiel und ebenso Regex sind Grundlagen die man lernen sollte wenn man programmieren möchte.
Das wird mind. 1000x im Internet erklärt und benötigt m.E. hier keine erneute Erklärung.

Gruß
Dan
Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

EnderPhilipp

Zitat von: DeeSPe am 26 Januar 2017, 16:38:30
So wie man split immer benutzt:
my @m = split("|",$mensamorgen);
...

Das hatte ich schon probiert, nur dann kam das:
   
K mit l und als Nachtisch o | p
¡¡¡ANFÄNGERALARM!!!
Raspberry Pi 3 (Hauptsystem)
Raspberry Pi B+ (Kellersonde)
Homematic,Philips Hue, LD382, nanoCul 433/868mhz, MPD, Intertechno, FIRMATA, EspEasy, SSCAM, STV, HDMI-CEC, EchoDot

DeeSPe

Zitat von: EnderPhilipp am 26 Januar 2017, 16:47:22
Das hatte ich schon probiert, nur dann kam das:
   
K mit l und als Nachtisch o | p
Ich hatte bei split mit | auch schon Probleme. Könnte daran liegen dass es evtl. ein geschütztes Zeichen ist und escaped werden muss.

Probiere mal mit escapen:
my $mensamorgen = ReadingsVal("Mensa", "Donnerstag", "");
my @m = split("\|",$mensamorgen);


Wenn das nicht geht mache es so:
my $mensamorgen = ReadingsVal("Mensa", "Donnerstag", "");
$mensamorgen =~ s/\|/;/g;
my @m = split(";",$mensamorgen);


Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

betateilchen

Ich wollte ja eigentlich nur ein PRINZIP beschreiben und keinen funktionsfähigen Code für copy&paste.
Ein bisschen Nachdenken und "Wissen aneignen" erwarte ich von jedem Benutzer.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen


sub test() {
  my $mensamorgen = 'Klopse "Königsberger Art" | mit Kartoffelpüree und Karotten in Butter | Himbeerjoghurt | G A1 C';
  $mensamorgen =~ s/\s\|\s/\|/g;
  my @m = split(/\|/,$mensamorgen);
  $m[1] =~ s/^mit//i;
  $m[1] =~ s/^und//i;
  $m[2] =~ s/^mit//i;
  $m[2] =~ s/^und//i;
  $mensamorgen = "$m[0] mit $m[1] und als Nachtisch $m[2] | $m[3]";
  fhem("setreading Mensa Morgen $mensamorgen");
  return $mensamorgen;
}


liefert als Ergebnis - siehe Anhang.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

EnderPhilipp

Zitat von: betateilchen am 26 Januar 2017, 17:32:38

sub test() {
  my $mensamorgen = 'Klopse "Königsberger Art" | mit Kartoffelpüree und Karotten in Butter | Himbeerjoghurt | G A1 C';
  $mensamorgen =~ s/\s\|\s/\|/g;
  my @m = split(/\|/,$mensamorgen);
  $m[1] =~ s/^mit//i;
  $m[1] =~ s/^und//i;
  $m[2] =~ s/^mit//i;
  $m[2] =~ s/^und//i;
  $mensamorgen = "$m[0] mit $m[1] und als Nachtisch $m[2] | $m[3]";
  fhem("setreading Mensa Morgen $mensamorgen");
  return $mensamorgen;
}


liefert als Ergebnis - siehe Anhang.

Danke, damit geht es.
Nur eine kleine "Abschlußfrage" wegen den Wochentagen:

Wie bekomme mache den Wert einer Variable aus einer if Abfrage in der ganzer Subroutine verfügbar ?

Mfg
Philipp
¡¡¡ANFÄNGERALARM!!!
Raspberry Pi 3 (Hauptsystem)
Raspberry Pi B+ (Kellersonde)
Homematic,Philips Hue, LD382, nanoCul 433/868mhz, MPD, Intertechno, FIRMATA, EspEasy, SSCAM, STV, HDMI-CEC, EchoDot


CoolTux

Wenn man am | splitten will dann am besten \\| bei split nehmen. Hatte ich bis jetzt den besten Erfolg.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

betateilchen

Zitat von: CoolTux am 27 Januar 2017, 07:53:45
Wenn man am | splitten will dann am besten \\| bei split nehmen. Hatte ich bis jetzt den besten Erfolg.

Man will aber nicht am "|" splitten, sondern am " | ", da sind nämlich noch Leerzeichen drumrum, die man erstmal weghaben will. Sonst gibt es im Ergebnis (mindestens) doppelte Leerzeichen.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

CoolTux

Ah. Wie immer steckt der Teufel im Detail.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net