Norbert Kölln: RegExp: Zahl x durch x Unterstreichungszeichen ersetzen

Moin, moin!

Ich habe in einer Textvariablen z. B. den String "blabla_11_irgendwas" und möchte sie möglichst mit Hilfe eines regulären Ausdrucks verändern. Relevant sind die Unterstreichungszeichen und die darin eingeschlossene Zahl. Als Ergebnis soll die Zahl verschwunden sein, der String soll 11 Unterstreichungszeichen (inklusive der vorher vorhandenen) enthalten.

Mir fehlt also ein Ausdruck wie
$text=~s/_(\d+)_/_{$1}/;
der aus "blabla_11_irgendwas" "blabla___________irgendwas" macht.

Hat jemand eine Idee?

Norbert

  1. Hallo Norbert,

    falls keine weitern "_" im String enthalten sind würde ich das so machen:
    ich würde die einzelenen Stringteile matchen und in $1, $2 und $3 schreiben, also nicht =~ s sonder mit =~ m.
    Zuerst alles von ^ bis inklusive "_" in $1,
    die Zahl in $2
    den Rest, ab "_" in $3.
    danach
    den Text zusammensetzen aus $1, dann in einer Schleife eine String bauen, das $2-mal "_" enthält und dann noch $3.

    das müsste einfach zu realisieren sein
    so long, wie wir coolen Saarländer sagen [S. Bernarding, 2002]
    Christoph

  2. hook,

    ich würd das jetzt auf die schnelle so machen:

    $text = "blabla_11_irgendwas";
    $text=~m/_(\d+)_/;
    $ersatz= _ x $1;
    $text=~s/_(\d+)_/$ersatz/;

    Gibt aber bestimmt besseres, aber bei Perl darf man ja alles, wenn es funktioniert :o)

    P.S.: Im Regex selbst greift man mit \1 auf das in der Klammer erkannte Muster
    zu.

    cya
    alligator

    1. Hi,

      Gibt aber bestimmt besseres,

      ja: den Schalter /e (mit der selben Funktion).

      P.S.: Im Regex selbst greift man mit \1 auf das in der Klammer erkannte Muster
      zu.

      Innerhalb des Patterns.

      Cheatah

      --
      X-Will-Answer-Email: No
      X-Please-Search-Archive-First: Absolutely Yes
      1. Hi,

        Gibt aber bestimmt besseres,

        ja: den Schalter /e (mit der selben Funktion).

        Aha gut zu wissen :o),
        1. gibt aber bei use warnings eine Warnung aus ( steht auch in der perldoc )
        2. ich komme nicht drauf, warum das dann bei mir ne Endlosschleife gibt
        denn \1 ist die Zahl 11 (zumindest wenn ich das /e weglasse):
        die Zahl 11:
        $text = "blabla_11_irgendwas";
        print $text."\n";
        $text=~s/_(\d+)_/_ x \1/e;
        print $text."\n";

        cya
        alligator

        1. Hi,

          1. gibt aber bei use warnings eine Warnung aus ( steht auch in der perldoc )

          ja, nebst Grund.

          $text=~s/_(\d+)_/_ x \1/e;

          Mein Kommentar zu Deiner Erwähnung von \1 war nicht ganz zufällig gewählt. Überlege Dir, was ich damit meine, und warum \1 hier falsch ist.

          Cheatah

          --
          X-Will-Answer-Email: No
          X-Please-Search-Archive-First: Absolutely Yes
          1. Hi

            $text=~s/_(\d+)_/_ x \1/e;

            Mein Kommentar zu Deiner Erwähnung von \1 war nicht ganz zufällig gewählt. Überlege Dir, was ich damit meine, und warum \1 hier falsch ist.

            ok mit $1 funktioniert es. Das heisst das /e aus dem RegExp rausspringt
            um den Code auszuführen und dann ja das Erkannte in $1 gespeicht ist. Aber
            was ist ausserhalb des RegEx in \1 gespeichert ? Warum ist dass denn dann
            kein Fehler sondern gibt mir da ne Endlosschleife?

            cya
            alligator

            1. Hi

              $text=~s/_(\d+)_/_ x \1/e;

              Mein Kommentar zu Deiner Erwähnung von \1 war nicht ganz zufällig gewählt. Überlege Dir, was ich damit meine, und warum \1 hier falsch ist.

              ok mit $1 funktioniert es. Das heisst das /e aus dem RegExp rausspringt
              um den Code auszuführen und dann ja das Erkannte in $1 gespeicht ist.

              Nein und Ja, RTFM. perlop und perlre.

              s/PAT/REPL/

              PAT ist ein regulärer Ausdruck. REPL nicht. REPL ist ein string, der den Interpolationsregeln von qq// unterworfen ist oder aber ein Perl-Ausdruck, der den Regeln der Perl-Syntax unterworfen ist, nämlich wenn /e verwendet wird.

              Aber was ist ausserhalb des RegEx in \1 gespeichert ? Warum ist dass denn dann
              kein Fehler sondern gibt mir da ne Endlosschleife?

              siehe perlre zu \1. Du willst \1 nicht.

  3. Moin, moin!

    ich würds immer noch so machen:
    if ($string =~ m/^(.*\)([0-9]*)(\.*)/)
    {
     my $count = 0;
     my $striche;
     while($count < $2)
     {
      $striche=$striche."\_";
      $count++;
     }
     my $ergebnis = $1.$striche.$3;
     print"Ergebnis= $ergebnis";
    }

    Das hat den großen Vorteil, dass man noch nach 2 Wochen weiß was es macht wund wie es das macht.
    so long, wie wir coolen Saarländer sagen [S. Bernarding, 2002]
    Christoph

    1. Moin, moin!

      *1

      ich würds immer noch so machen:

      sicher?

      if ($string =~ m/^(.*\)([0-9]*)(\.*)/)
      {
      my $count = 0;
      my $striche;
      while($count < $2)
      {
        $striche=$striche."\_";
        $count++;
      }
      my $ergebnis = $1.$striche.$3;
      print"Ergebnis= $ergebnis";
      }

      Das hat den großen Vorteil, dass man noch nach 2 Wochen weiß was es macht wund wie es das macht.

      Ich würde mich schon nach 2 Stunden fragen, welche komplexen Berechnungen ich da in 12 Zeilen Code anstellen lasse. Ausserdem würden mich schon beim ersten mal die uninitialized-Warnungen in der Zeile '$striche = $striche."\_"' nerven.

      btw.: _ ist kein Sonderzeichen, weder in strings, noch in regulären Ausdrücken.

      so long, wie wir coolen Saarländer sagen [S. Bernarding, 2002]

      bezüglich *1: Sagen die Saarländer wirklich "Moin, moin" ?

      Christoph

      Richard, kein Saarländer

  4. Nochmals moin, moin!

    Vielen Dank für die Hilfe, geklappt hat es mit
    $zeile=~s/_(\d+)_/"_" x $1/ge;

    Der Dank geht natürlich auch an Christoph, der einen nun nicht realisierten Vorschlag gemacht hat.

    Norbert