[PERL] Mit Regex kompletten String durchsuchen und ersetzen

Dieses Thema im Forum "Ruby, php, Perl, Python ..." wurde erstellt von dummschnigger, 16.04.2007.

  1. #1 dummschnigger, 16.04.2007
    Zuletzt bearbeitet: 16.04.2007
    dummschnigger

    dummschnigger Grünschnabel

    Dabei seit:
    16.04.2007
    Beiträge:
    3
    Zustimmungen:
    0
    Hallo alle zusammen,

    ich habe ein Problem mit Regex in einem Perlscript. Ich möchte eine Templatedatei einlesen, bestimmte Werte ersetzen und die Daten danach in eine neue Datei schreiben. Einlesen und Ausgabe funzt. Ich lese die Datei komplett in einen String ein und bearbeite diesen dann mit einem regulären Ausdruck. In einer Steuerdatei stehen die ganzen Werte sowie die Ersetzungen drin.

    Code:
    host|ip
    test1|192.168.1.1
    test2|192.168.1.2
    
    Folgende Variablen habe ich:
    Code:
    $tpl            -> die Templatedatei
    @replace_titles -> Die Werte die gesucht werden sollen
    @tmp_cfg        -> Die Werte die dann eingefügt werden sollen
    
    Script:
    Code:
      foreach my $line (@tmp_cfg) {
        my $tmp_tpl = $tpl;
        chomp($line);
        my @replace = split(/\|/, $line);
    
        for(my $c = 0; $c <= $#replace; $c++) {
          my $regex = 's/\{\{' . $replace_titles[$c] . '\}\}/' . $replace[$c] . '/egimox';
          $tmp_tpl =~ $regex;
        }
        print $tmp_tpl;
      }
    
    Das steht dann in den Variablen drin:
    Code:
    @replace_titles[0] = 'host'
    @replace_titles[1] = 'ip'
    ...
    @tmp_cfg[0] = 'test1|192.168.1.1'
    @tmp_cfg[1] = 'test2|192.168.1.2'
    ...
    @replace[0] = 'test1'
    @replace[1] = '192.168.1.1'
    
    Meine Templatedatei sieht so aus
    Code:
    Hostname {{host}}
    IP-Add {{ip}}
    
    Es soll jetzt nach allen Werten in @replace_titles gesucht werden, die sich in einer doppelt geschweiften Klammer befinden und ersetzt werden.

    Wenn ich das Script laufen lasse, dann bekomme ich mit dem "print $tmp_tpl;" nur den Inhalt der Templatedatei angezeigt, ohne dass die Veränderungen vorgenommen werden.

    Wo ist mein Fehler? Ich schätze mal, dass irgendwas mit dem Ausdruck nicht stimmt, wahrscheinlich mit den Parametern hintendran.

    Ich wäre für jegliche Hilfe dankbar.

    /edit:
    Die Suchwörter können auch mehrfach vorkommen und dann sollten alle auch ersetzt werden, z.B.:
    Code:
    Hostname {{host}}
    IP-Add {{ip}}
    Irgendwas {{host}}
    
    /edit2:
    ich habe gerade mal folgendes getestet:
    Code:
    $tmp_tpl =~ s/{{hostname}}/test1/g;
    
    Wenn ich das so ausführe, wird das einwandfrei ersetzt. Anscheinend hängt es damit zusammen, wie ich den Ausdruck aufbaue.

    Wenn ich den Ausdruck so aufbaue:
    Code:
    my $regex = s/\{\{$replace_titles[$c]\}\}/$replace[$c]/g;
    
    dann bringt er mir diese Fehlermeldung:
    Code:
    Use of uninitialized value in substitution (s///) at ./create_cfg.pl line 112.
    
    Irgendjemand 'ne Idee wie ich meine Variablen da rein bekomme?
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. #2 Wolfgang, 16.04.2007
    Zuletzt bearbeitet: 16.04.2007
    Wolfgang

    Wolfgang Foren Gott

    Dabei seit:
    24.04.2005
    Beiträge:
    3.978
    Zustimmungen:
    0
    Ort:
    Erfurt
    Hallo

    Wenn im $tmp_tpl wirklich ein multilinestring steht, dann brauchst du die Option m. Wozu du x und e hier einfügst, ist nicht klar.
    Ich sehe weder ausführbaren Code noch Kommentare in dem Replaceteil.

    Außerdem würde ich statt 2 Array lieber ein hash verwenden.
    Der Schlüssel sei der Suchtext und der Wert der Replace-Text.
    Dadurch stellst du auch gleich sicher, dass die Größe gleich groß ist.
    Da du offensichtlich use strict verwendest (wie es sein soll) , könnte dein Fehler an einem Fehlenden Index liegen. Sprich das Ersetzungsarray ist kleiner als das Sucharray.
    Das beschriebene Suchhash sei hier hash.
    Code:
    foreach (keys  %hash) {
         $tmp_tpl= ~s/\{\{'$_'\}\}/' $hash{$_} '/gim';
          
        }
        print $tmp_tpl;
    
    Ob es geht kann ich nicht testen, da das nur ein Fragment ist.
    BTW wozu eigentlich die Punkte?
    Gruß Wolfgang
     
  4. #3 dummschnigger, 17.04.2007
    Zuletzt bearbeitet: 17.04.2007
    dummschnigger

    dummschnigger Grünschnabel

    Dabei seit:
    16.04.2007
    Beiträge:
    3
    Zustimmungen:
    0
    Hallo Wolfgang, danke für deine Hilfe.

    Ich hatte das Problem heute mittag auf der Arbeit und kurz vor Feierabend habe ich dann die Lösung gefunden. Da ich dann keine Zeit mehr hatte die Lösung zu posten werde ich das morgen nachholen.

    Das hatte ich in einem Tutorial so gefunden. Da ich in Perl noch relativ frisch bin dachte ich mir, dass ich es mit den Optionen einfach mal ausprobiere und das war dann der letzte Stand, bevor ich es hier gepostet hatte.

    Das soll nur bedeuten das es da noch weitergeht, ich es aber gekürzt habe ;)
    .
    .
    .
    EDIT (autom. Beitragszusammenführung) :
    .

    So, hier meine "Lösung" für das Problem.

    Code:
    for(my $c = 0; $c <= $#replace; $c++) {
      $tmp_tpl =~ s/{{$replace_titles[$c]}}/${replace[$c]}/g
    }
    
    So funktioniert es einwandfrei. Irgendwie hatte ich Probleme die Variablen gescheit in den regulären Ausdruck zu packen. In $replace_titles sind die Wörter drin die gesucht werden sollen und in $replace sind die Ersetzungen drin.
     
  5. #4 Wolfgang, 17.04.2007
    Zuletzt bearbeitet: 17.04.2007
    Wolfgang

    Wolfgang Foren Gott

    Dabei seit:
    24.04.2005
    Beiträge:
    3.978
    Zustimmungen:
    0
    Ort:
    Erfurt
    Hallo
    Schön, dass du es lösen konntest.
    Allerdings hast du meine Frage nach den Punkten missverstanden.
    Code:
    s/\{\{'[b][color=red] .[/color][/b] $replace_titles[$c] [b][color=red] .[/color][/b] '\}\}/' [b][color=red] .[/color][/b] $replace[$c] [b][color=red] .[/color][/b] '/
    
    Diese Punkte meinte ich.
    Ein Punkt bedeutet nämlich im Suchteil ein beliebiges Zeichen
    Im Ersetzen Teil in verbindung mit Option e eine Stringverknüpfung.

    Die von mir vorgeschlagene Hashlösung ist allerdings IMHO übersichtlicher.
    Aber viele Wege führen Nach Rom.

    Gruß Wolfgang
    EDIT:
    Du solltest bei deiner Lösung jedoch vorher prüfen, ob die Arrayindexe auch existieren, bzw. beide Arrays wirklich gleich groß sind. Sonst könnte es zu einem unerwarteten Abbruch kommen.
     
  6. #5 dummschnigger, 17.04.2007
    dummschnigger

    dummschnigger Grünschnabel

    Dabei seit:
    16.04.2007
    Beiträge:
    3
    Zustimmungen:
    0
    Ah ok, dann hatte ich dich missverstanden ;) Ich dachte eigentlich, dass ich damit die einzelnen Teile zusammensetzen kann. Quasi wie eine Stringverkettung.

    Das werde ich mir nochmal zu Gemüte führen. Das Problem war, dass ich das Script heute morgen gebraucht habe und da musste es einfach nur funktionieren.

    s.o., danke für den Hinweis, das werde ich noch einbauen.
     
  7. #6 angelsfall, 17.04.2007
    angelsfall

    angelsfall Routinier

    Dabei seit:
    09.05.2005
    Beiträge:
    315
    Zustimmungen:
    0
    Ort:
    Berlin
    Regexe in Perl sind schon von Natur aus in den Double-Quotes, d.h. darin enthaltene Variablen und Sonderzeichen werden geparst (dies ist der Unterschied zu den Single-Quotes, bei denen Sonderzeichen und Variablennamen praktisch wörtlich genommen werden).
     
  8. Anzeige

    Vielleicht findest du HIER Antworten.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
Thema: [PERL] Mit Regex kompletten String durchsuchen und ersetzen
Besucher kamen mit folgenden Suchen
  1. Abbrucharbeiten Perl

    ,
  2. perl regex suchen ersetzen

    ,
  3. perl string durchsuchen

    ,
  4. perl regex strings ersetzen
Die Seite wird geladen...

[PERL] Mit Regex kompletten String durchsuchen und ersetzen - Ähnliche Themen

  1. [Perl] Perl OO Methodenaufruf in anderem Objekt

    [Perl] Perl OO Methodenaufruf in anderem Objekt: Hallo, Ich bin dabei in Perl ein Pokerspiel zu programmieren, hänge aber momentan an einem Problem, wo ich nicht weiterkomme. Ich habe die...
  2. [Perl] Check auf Referenz...Hash

    [Perl] Check auf Referenz...Hash: Hallo! Mal ne kleine Frage. Gibt es ein Funktion mit der ich checken kann, ob in einem Hash der Value eine Referenz auf einen weiter Hash...
  3. [Perl]: Mehr als ein Objekt auf einmal instanziieren

    [Perl]: Mehr als ein Objekt auf einmal instanziieren: Hallo zusammen, ich benutze zurzeit Net::FTPSSL zum Aufbau einer FTP Connection. Mein Problem ist, wenn ich z.B. eine Verbindung zu 5...
  4. [Perl] Script zum ändern der Signatur in vB-Boards

    [Perl] Script zum ändern der Signatur in vB-Boards: Hallo, folgendes Script funktioniert beim gulli:board , aber leider nicht hier: #!/usr/bin/perl use LWP::UserAgent; $agent = new...
  5. [Perl] Namespace Probleme

    [Perl] Namespace Probleme: Hallo zusammen, irgendwie scheitere ich gerade daran, meine sehr lange Hauptdatei in viele Module (*.pm) mit einem Steuerprogramm (.pl) zu...