andy: variable in regulären ausdruck...

Hallo,

habe folgendes Problem.

Habe eine Datei1 die enthält folgendes:
<Ziffer><leerzeichen><URL><tabulator><String>
bsp:
1 http://www.url1.de/impressium.html Impressium
2 http://www.blabla.de/blabla/bla/ueber_uns.html Wir Über uns!
3 http://url.de/home/ Home
...
..
.

und ich habe noch eine andere Datei2 die nur eine Liste von Strings enthält.

bsp:

Impressium
Home
Kontakt
Besuchen Sie uns
Bla Bla Bla
...
..
.

aus der ersten Datei möchte ich NUR (nicht die ganze Zeile) die URL-s extrahieren, dessen <String> (das Teil nach dem Tabulator) auch in der Datei2 vorkommt. Die anderen URL möchte ich nicht extrahieren.
Ergebniss wäre hier:

http://www.url1.de/impressium.html
http://url.de/home/

ich habe so angefangen:

Datei1

open INPUT, "$ARGV[0]" or die ("datei $ARGV[0] nicht gefunden");
my @Datei1 = <INPUT>;
close(INPUT);

Datei2

open(DATEI, "<datei2.txt") || die "Datei nicht gefunden";
my @Datei2 = <DATEI>;
close(DATEI);

my @Ergebniss;

foreach my $datei2 (@Datei2) {

foreach my $zeilen (@Datei1) {

$zeilen =~ /([1] )([http://].+)(\t)(.+)/gi;

if ($4 =~ /$datei2/){

push(@Ergebniss,$2)

}
else {}
}
}

Leider funktioniert der Script nicht so. Ich habe in der @Ergebniss nicht das was ich wollte, und ich weiss auch nicht wo der Fehler ist, vermutte aber dass "if ($4 =~ /$datei2/)" nicht ganz korrekt ist, oder liegt es in der schleife???
kann mich jemand vielleicht helfen?

vielen Dank,

Gruss, Andy


  1. 0-9 ↩︎

  1. Tag andy.

    Habe eine Datei1 die enthält folgendes:
    <Ziffer><leerzeichen><URL><tabulator><String>
    und ich habe noch eine andere Datei2 die nur eine Liste von Strings enthält.
    [...]
    aus der ersten Datei möchte ich NUR (nicht die ganze Zeile) die URL-s extrahieren, dessen <String> (das Teil nach dem Tabulator) auch in der Datei2 vorkommt. Die anderen URL möchte ich nicht extrahieren.

    Ich würde so vorgehen, dass ich zunächst die Strings aus Datei1 als Schlüssel eines Hashs verwende, entweder gleich beim Einlesen oder über einen Hash-Slice:

    my %liste;  
    open(DATEI, $datei1) or die $!;  
    flock(DATEI, LOCK_SH);  
    while(<DATEI>) {  
      $liste{chomp($_)} = "";  
    }  
    close(DATEI);
    

    Im nächsten Schritt würde ich die Zeilen von Datei2 einlesen, splitten und mit den Hash-Schlüsseln vergleichen:

    open(DATEI, $datei2) or die $!;  
    flock(DATEI, LOCK_SH);  
    while(<DATEI>) {  
      chomp($_);  
      my @dummy = split(/\s/, $_);  
      if(exists $liste{$dummy[2]}) {  
        $liste{$dummy[2]} = $dummy[1];  
      }  
    }  
    close(DATEI);
    

    Das ergibt einen Hash folgender Struktur: $liste{'Bezeichnung'} = 'url', mit dem du dann weiterarbeiten kannst.

    Übrigens:

    open INPUT, "$ARGV[0]" or die ("datei $ARGV[0] nicht gefunden");

    ist böse, siehe perlsec.

    Siechfred

    1. Hallo Siechfred,

      vielen Dank für die Hilfe aber trotzdem es funktioniert nicht.

      $datei1 enthält ja folgende liste:

      eintrag1
      eintrag2
      eintrag3
      ...
      ..
      .

      my %liste;

      open(DATEI, $datei1) or die $!;
      flock(DATEI, LOCK_SH);
      while(<DATEI>) {
        $liste{chomp($_)} = "";
      }
      close(DATEI);

      Wenn ich hier alle schlüsseln printen lasse kommt ja nichts???
      my @schluessel = keys(%liste)

      foreach (@schluessel){

      print "$liste{$schluessel)\t $schluessel\n";

      }

      $datei2 enthält ja folgende liste:

      1 http://www.fdfdfd.de/dfd/ eintrag1
      2 http://www.fdfdfd.de/dfd/ eintrag133
      2 http://www.fdfdfd.de/dfd/test/2.html eintrag1

      Im nächsten Schritt würde ich die Zeilen von Datei2 einlesen, splitten und mit den Hash-Schlüsseln vergleichen:

      open(DATEI, $datei2) or die $!;
      flock(DATEI, LOCK_SH);
      while(<DATEI>) {
        chomp($_);
        my @dummy = split(/\s/, $_);
        if(exists $liste{$dummy[2]}) {
          $liste{$dummy[2]} = $dummy[1];
        }
      }
      close(DATEI);

      hier ist das Problem: wenn es einen schlüssel gibt (bsp. hier eintrag1) der schon öfters vorkommt wird dessen alter wert einfach mit dem neuen Wert überschrieben! (hier wäre das Ergebniss $liste{'eintrag1'} = 'http://www.fdfdfd.de/dfd/test/2.html' und 'http://www.fdfdfd.de/dfd/' wäre verloren gegangen.
      Das will ich aber nich, Ich möchte allte Werte haben.

      Ich habe trotzdem vielen Versuchen noch kein Lösung gefunden.
      Können Sie mich vielleicht weiter helfen?

      vielen Dank,

      Gruss, Andy

      1. Tag andy.

        vielen Dank für die Hilfe aber trotzdem es funktioniert nicht.

        Ja, habe ich im Nachhinein auch gesehen, er verschluckt sich an dieser Zeile:

        $liste{chomp($_)} = "";

        Wenn du die aufdröselst in

        chomp($_);  
        $liste{$_} = "";
        

        müsste es funktionieren.

        my @schluessel = keys(%liste)
        foreach (@schluessel){
          print "$liste{$schluessel)\t $schluessel\n";
        }

        Warum so kompliziert, siehe Schleifen und Hashes.

        hier ist das Problem: wenn es einen schlüssel gibt (bsp. hier eintrag1) der schon öfters vorkommt wird dessen alter wert einfach mit dem neuen Wert überschrieben!

        Ja, das ist das richtige Verhalten.

        Das will ich aber nich, Ich möchte allte Werte haben.

        Dann weise sie statt dem Hash einem neuen Array zu. Damit ginge aber jede Relation zwischen Datei1 und Datei2 verloren. Willst du das nicht, wäre evtl. ein Hash of Arrays was für dich.

        Siechfred