jonny: Zeile Splitten und in Variable packen

Hallo,

bisher bin ich immer wie folgt vorgegangen, um eine bestimmte Spalte aus einer Zeile ausgeben zu lassen.

Beispiel...

Inhalt einer Datei:
xxx;dies;xxx;xxx
xxx;ist;xxx;xxx
xxx;ein;xxx;xxx
xxx;test;xxx;xxx

meine Schleife:

open(DT,"<Datei");
while(<DT>) {
   my @part=split /;/,$_;
   print "$part[1]\n";

}

Nun finde ich das sehr umständlich. Gibt es eine bessere Methode, die richtige Spalte aus der Zeile zu ziehen? Ich hatte es mal mit push versucht, aber das habe ich leider nicht hinbekommen - zum Einen will push ein Array statt eine Variable und da kommen immer ARRAY{...}'s heraus :-)

push $daten [(split /;/)[1]],$_;

Was mache ich da falsch?

Mfg,
Jonny

  1. Sup!

    open(DT,"<Datei");
    while(<DT>) {

    $_ =~ /.*?;(.*?);.*/;

    print $1."\n";

    }

    Könnte auch klappen. Hab's aber nicht getestet. Die Idee ist, mit dem RegExp genau die Sachen zwischen dem ersten und zweiten ; rauszufiltern und in $1 speichern zu lassen.

    Gruesse,

    Bio

    --
    Keep your friends close, but your enemies closer!
    1. $_ =~ /.*?;(.*?);.*/;

      Hierbei solltest Du angeben, daß die Zeichen zwischen den ; keine ; sein dürfen. Im Moment läßt Du alles zu, weswegen der Ausruck bei mehr als drei ; nicht funktionieren würde.
      $_ =~ /[1]+;([^;]+);[^;]/;

      So kreigst Du immer den zweiten Abschnitt, da auch noch der Anfang gesetzt ist und es kann nach dem 3. Abschnitt noch mehr kommen.

      Viele Grüße

      Sasha


      1. ^; ↩︎

      1. Sup!

        Hierbei solltest Du angeben, daß die Zeichen zwischen den ; keine ; sein dürfen. Im Moment läßt Du alles zu, weswegen der Ausruck bei mehr als drei ; nicht funktionieren würde.
        $_ =~ /[1]+;([^;]+);[^;]/;

        So kreigst Du immer den zweiten Abschnitt, da auch noch der Anfang gesetzt ist und es kann nach dem 3. Abschnitt noch mehr kommen.

        Nach meiner Interpretation matcht mein Ausdruck

        $_ =~ /.*?;(.*?);.*/;

        auch immer den zweiten Abschnitt.

        Zuerst wird non-greedy alles gematcht bis zum ersten Semikolon (darum müssen Semikola nicht ausgeschlossen werden, denn .*? kann auch *gar nichts* matchen.
        Dann wird non-greedy gematcht bis zum zweiten Semikolon (also der zweite Abschnitt) und wegen der Klammern in $1 gespeichert, das letzte .* matcht dann greedy den Rest.

        Gruesse,

        Bio

        --
        Keep your friends close, but your enemies closer!

        1. ^; ↩︎

        1. $_ =~ /.*?;(.*?);.*/;

          auch immer den zweiten Abschnitt.

          hi Bio, ja das klappt auch und genau sowas ähnliches hatte ich als Beispiel selber im Kopf, aber vor einigen Tagen hatte ich mal ein nettes Beispiel mit push und split gesehen - ich glaube es war mein eigener Thread :-) - und wollte es auf diese Weise.

          Danke dennoch für deine Hilfe! Dein Beispiel lässt sich woanders bei mir einsetzen :-)

          Mfg,
          Jonny

      2. Hallo,

        das würde mir aber leider nichts bringen, da die Spaltennummer unterschiedlich sein kann, die ich herausfischen möchte.

        $_ =~ /[1]+;([^;]+);[^;]/;

        push @daten, (split /;/, $_)[$var];

        ist mir da schon angenehmer!

        Mfg,
        Jonny


        1. ^; ↩︎

    2. Könnte auch klappen. Hab's aber nicht getestet. Die Idee ist, mit dem RegExp genau die Sachen zwischen dem ersten und zweiten ; rauszufiltern und in $1 speichern zu lassen.

      Das geht einfacher (split /;/, $_)[1]

      Struppi.

  2. hi!

    push $daten [(split /;/)[1]],$_;
    Was mache ich da falsch?

    Ungetestet wuerde ich mal sagen, dass das eher ungefaehr so aussehen
    muesste:

    while (<DATA>) {
      push @daten, (split /;/, $_)[1];
    }

    Falls du uebrigens in einem $skalar eine Array-Referenz hast (also
    dieses ARRAY(...)), kannst du das mit @$skalar aufloesen. Falls das
    aber unbeabsichtigt auftritt, hast du eher schon im Vorfeld einen
    Fehler gemacht.

    bye, Frank!

    --
    Never argue with an idiot. He will lower you to his level and then
    beat you with experience.
    1. Hallo Frank,

      while (<DATA>) {
        push @daten, (split /;/, $_)[1];
      }

      ungetestet hast du recht! :-)

      Mfg,
      Jonny

  3. bisher bin ich immer wie folgt vorgegangen, um eine bestimmte Spalte aus einer Zeile ausgeben zu lassen.

    Scheiont du hast das mit den Referenzen dich nicht so ganz kapiert.

    meine Schleife:

    open(DT,"<Datei");
    while(<DT>) {
       my @part=split /;/,$_;
       print "$part[1]\n";

    }

    Nun finde ich das sehr umständlich. Gibt es eine bessere Methode, die richtige Spalte aus der Zeile zu ziehen? Ich hatte es mal mit push versucht, aber das habe ich leider nicht hinbekommen - zum Einen will push ein Array statt eine Variable und da kommen immer ARRAY{...}'s heraus :-)

    push $daten [(split /;/)[1]],$_;

    Nicht schlecht, aber falsch. Ob du für Daten einenen Skalar (als referenz) oder ein Array nimmst spielt erst mal keine Rolle. Wenn du das Array an Funktionen weitergeben willst, solltest du aber eine Referenz nehmen.

    Was mache ich da falsch?

    Du willst vermutlich:

    my $daten = [];

    while(<DT>) {
    push @$daten, (split /;/, $_)[1];
    }

    Struppi.

    1. Hallo Struppi,

      Scheiont du hast das mit den Referenzen dich nicht so ganz kapiert.

      das hast du richtig erkannt :-) bin noch am lernen!

      while(<DT>) {
      push @$daten, (split /;/, $_)[1];
      }

      genau das! aber @$daten kapier ich nicht! mennohhhh!

      Mfg,
      Jonny