Assa: string terminator??

Hallo!
Vorweg: ich bin absoluter Perl-Anfänger. Ich habe ein kleines Übungsskript, das nach bestimmten Zahlen aus einer eingelesenen Textdatei suchen soll. Derzeit sieht das Skript so aus:
---
#!/usr/bin/perl -w

use strict;

print "Bitte Dateinamen inkk. Pfad eingeben: ";
my $dateiname = <>;

open (DATEI, $dateiname) or die "Datei kann nicht ge\x94ffnet werden";

undef $/;

my $text = <DATEI>;

if ($text =~m/^(6\d{4,8})/q) {
  print "Zahlenmuster gefunden\n";
}

close(DATEI);
---

Wenn ich dieses Skript so ausführe, erhalte ich folgende Fehlermeldung: "syntax error at C:.... line 18, near "close(DATEI)"  (Might be a runaway multi-line )) string starting on line 14)
Execution of C.... aborted due to compilation errors."

Line 14 ist die if-Zeile und line 18 die close(DATEI)-Zeile.

Nehme ich Zeile 18 raus, erhalte ich eine andere Fehlermeldung:
"Can't find string terminator ")" anywhere before EOF at C:... line 14."
Das ist wie gesagt die if-Zeile.

Was ist da falsch? Kann mir jemand auf die Sprünge helfen?

  1. Hallo Assa!

    open (DATEI, $dateiname) or die "Datei kann nicht ge\x94ffnet werden";

    Es ist oft ratsam, sich den Grund eines fehlerhaften open ausgeben zu lassen:
    die "Datei kann nicht ge\x94ffnet werden, weil: $!";

    if ($text =~m/^(6\d{4,8})/q) {

    .............................^
    was soll das für ein Flag sein? Bekannt sind mir nur die hier. Liegt das vielleicht daran? ;)

    if m/pattern/;
    ...^

    Da die Slahs die Default-Delimiter sind, brauchst Du m hier nicht. Erst wenn Du andere benutzt, z.B.:

    if m!pattern!;

    Viele Grüße aus Frankfurt/Main,
    Patrick

    --

    _ - jenseits vom delirium - _
    [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
    Nichts ist unmöglich? Doch!
    Heute schon gegökt?
    1. Danke Patrick!

      Das q war ja wirklich Blödsinn. Da hätte ich einfach mal prüfen sollen, das sollte ein g sein. Jetzt gehts - und das m ist wirklich nicht notwendig, wobei ich sagen muss, dass ich deinen Satz:
      "Da die Slahs die Default-Delimiter sind, brauchst Du m hier nicht. Erst wenn Du andere benutzt, z.B.:"
      ...nicht verstehe. Aber da muss ich mich einfach noch mehr mit Perl beschäftigen...

      Danke!

      1. Hallo Assa!

        "Da die Slahs die Default-Delimiter sind, brauchst Du m hier nicht. Erst wenn Du andere benutzt, z.B.:"
        ...nicht verstehe. Aber da muss ich mich einfach noch mehr mit Perl beschäftigen...

        Delimiter sind Grenzen. Wenn Du z.B einen String definierst, brauchst Du auch Delimiter. Diese sind "" oder '':

        my $string = "Hallo Welt!";
        print "Heute ist ein schöner Tag zum Perlen\n";

        Reguläre Ausdrücke brauchen auch Delimiter. Defaultmäßig werden Slashs benutzt:

        print $string if /Welt!/; # $string enthält »Welt!«, »Hallo Welt!« wird ausgegeben.

        Du kannst aber andere Delimiter benutzen. Wichtig ist, dass diese im Suchausdruck nicht vorkommen, denn da müssen sie escaped (mit einem Backslash: ) werden.

        Nehmen wir an, Du musst einen Serverpfad oder Teile einer URI manipulieren. Diese enthalten ja Slashs:

        $path = "/home/user/public/myweb/pics/mypic.jpg"
        print $path if /\home/user/public/myweb/pics/;

        Sieht etwas unübersichtlich aus, nicht wahr? Aber man kann ja andere Delimiter nehmen:

        print $path if m!/home/user/public/myweb/pics!;
        oder:
        print $path if m#/home/user/public/myweb/pics#;

        Hier wird m benötigt, damit Perl weiß, dass ein RegExp folgt. Mit den Slahs als Default-Delimiter weiß Perl das von selbst.

        Bei unserem Beispielstring vom Beginn: Hallo Welt! müssen wir, falls wir ! als Delimiter nehmen, was machen?

        print if m!Welt!!; # AUA, das tut weh!
        print if m!Welt!!; # Schon besser.

        Viele Grüße aus Frankfurt/Main,
        Patrick

        --

        _ - jenseits vom delirium - _
        [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
        Nichts ist unmöglich? Doch!
        Heute schon gegökt?
        1. Hey Patrick,

          vielen Dank! Das hab ich schon mal gecheckt! Sehr nett von dir, mir das nochmal so ausführlich zu erklären!

  2. Ein Hinweis scheint mir enorm wichtig:

    undef $/;

    Das ist sehr, sehr böse. $/ ist eine globale Perlvariable, und derartige Variablen sollten *niemals* einfach so überschrieben werden. Für die vorübergehende Manipulation, z.B. um eine Datei in einen Skalar statt in ein Array einzulesen, gibt es den local-Operator und anonyme Blöcke:

    {  
      local $/;  
      my $inhalt = <FILE>;  
    }
    

    Obiger Code bewirkt, dass für den anonymen Block (also alles zwischen „{“ und „}“) dem globalen $/ vorübergehend ein anderer Wert - nämlich undef - zugewiesen wird. Außerhalb dieses Blocks hat $/ den von Perl standardmäßig zugewiesenen Wert. Das ist wichtig, wenn Du innerhalb eines Projektes mehrere Operationen an Dateien durchführst. Man stelle sich nur vor, dass Du eine Datei in einem Rutsch einlesen willst, eine andere aber zeilenweise. Das dürfte mit undef $/ gründlich in die Hose gehen.

    Siechfred

    --
    Hinter den Kulissen passiert viel mehr, als man denkt, aber meistens nicht das, was man denkt.