FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: EnderPhilipp am 26 Januar 2017, 06:59:33

Titel: Perl Zeichenkette in Zeichenkette einsetzten
Beitrag von: EnderPhilipp am 26 Januar 2017, 06:59:33
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
Titel: Antw:Perl Zeichenkette in Zeichenkette einsetzten
Beitrag von: betateilchen am 26 Januar 2017, 07:38:09
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)
Titel: Antw:Perl Zeichenkette in Zeichenkette einsetzten
Beitrag von: EnderPhilipp am 26 Januar 2017, 08:05:06
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
Titel: Antw:Perl Zeichenkette in Zeichenkette einsetzten
Beitrag von: betateilchen am 26 Januar 2017, 08:15:00
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.
Titel: Antw:Perl Zeichenkette in Zeichenkette einsetzten
Beitrag 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
Titel: Antw:Perl Zeichenkette in Zeichenkette einsetzten
Beitrag von: DeeSPe am 26 Januar 2017, 16:38:30
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
Titel: Antw:Perl Zeichenkette in Zeichenkette einsetzten
Beitrag von: EnderPhilipp am 26 Januar 2017, 16:47:22
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
Titel: Antw:Perl Zeichenkette in Zeichenkette einsetzten
Beitrag von: DeeSPe am 26 Januar 2017, 16:55:26
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
Titel: Antw:Perl Zeichenkette in Zeichenkette einsetzten
Beitrag von: betateilchen am 26 Januar 2017, 17:24:00
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.
Titel: Antw:Perl Zeichenkette in Zeichenkette einsetzten
Beitrag 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.
Titel: Antw:Perl Zeichenkette in Zeichenkette einsetzten
Beitrag von: EnderPhilipp am 27 Januar 2017, 06:42:02
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
Titel: Antw:Perl Zeichenkette in Zeichenkette einsetzten
Beitrag von: dev0 am 27 Januar 2017, 06:52:38
https://perlmaven.com/scope-of-variables-in-perl
Titel: Antw:Perl Zeichenkette in Zeichenkette einsetzten
Beitrag 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.
Titel: Antw:Perl Zeichenkette in Zeichenkette einsetzten
Beitrag von: betateilchen am 27 Januar 2017, 09:16:24
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.
Titel: Antw:Perl Zeichenkette in Zeichenkette einsetzten
Beitrag von: CoolTux am 27 Januar 2017, 09:20:30
Ah. Wie immer steckt der Teufel im Detail.