xNeTworKx: Der gierige Quantifizierer ?

Hallo,
wie ich ein Verzeichnis am Server nach .html Dateien durchsucht habe, habe ich einen gierigen Quantifizierer benutzt, nämlich so :
      if ($file =~ /.*.html/)   {
Jetzt wurden zwar alle Dateien eingelesen, aber er hat von den 4 html Dateien, 5 gefunden, nämlich eine Datei, die nur .html hieß, was aber Unsinn is, weil so eine Datei gar nicht existiert.
Das Ganze funktionierte erst wieder richtig als ich den Ausdruck auf:
      if ($file =~ /.+.html/)   {
änderte.
Weis jemand warum das so ist ?

  1. Hoi,

    [...]

    Weis jemand warum das so ist ?

    IMHO ist das so nicht beantwortbar. Kannst du noch mehr Code posten? Oder, noch lieber,
    den Code irgendwo online stellen?

    Gruss,
     CK

    1. Hallo!

      IMHO ist das so nicht beantwortbar. Kannst du noch mehr Code posten? Oder, noch lieber,
      den Code irgendwo online stellen?

      Doch ist es schon, auch ohne Code, allerdings ist es in SelfHTML soweit ich weiß falsch beschrieben.

      * sucht 0 oder mehr Zeichen,
      während

      • 1 oder mehr Zeichen sucht
        zB

      ^x* passt sowohl auf "xdsl als auch auf "dsl", da beides mit 0 oder mehr x beginnt, während ^x+ nur auf xdsl passen würde.

      Adios

      1. Hoi,

        Doch ist es schon, auch ohne Code, allerdings ist es in SelfHTML soweit ich weiß falsch
        beschrieben.

        Ne, ist es nicht.

        * sucht 0 oder mehr Zeichen,
        während

        • 1 oder mehr Zeichen sucht
          zB

        Ja, das ist mir bewusst.

        ^x* passt sowohl auf "xdsl als auch auf "dsl", da beides mit 0 oder mehr x beginnt, während
        ^x+ nur auf xdsl passen würde.

        Auch das.

        Aber erklaere mir doch bitte, warum .html gefunden wird bei einem Directory-Listing, wo es keine
        Datei mit dem Namen '.html' gibt, ich habe es nicht verstanden.

        Gruesse,
         CK

        1. Hallo

          Ne, ist es nicht.

          Doch, zumindest in der ersten Downloadversion von SH8.0 war es vertauscht

          Aber erklaere mir doch bitte, warum .html gefunden wird bei einem Directory-Listing, wo es keine
          Datei mit dem Namen '.html' gibt, ich habe es nicht verstanden.

          Kann ich dir nicht sagen, aber xNetworkx wirds wahrscheinlich erkennen können, mit dem Wissen um den Unterschied zwischen + und *.

          1. Hoi,

            Ne, ist es nicht.
            Doch, zumindest in der ersten Downloadversion von SH8.0 war es vertauscht

            Das meinte ich doch gar nicht. Ich meinte, dass das Problem mit deiner Antwort nicht geklaert war.

            Aber erklaere mir doch bitte, warum .html gefunden wird bei einem Directory-Listing, wo es keine
            Datei mit dem Namen '.html' gibt, ich habe es nicht verstanden.

            Kann ich dir nicht sagen, aber xNetworkx wirds wahrscheinlich erkennen können, mit dem Wissen
            um den Unterschied zwischen + und *.

            Anscheinend ja nicht.

            Gruss,
             CK

        2. Hallo,

          Aber erklaere mir doch bitte, warum .html gefunden wird bei einem Directory-Listing, wo es keine
          Datei mit dem Namen '.html' gibt, ich habe es nicht verstanden.

          Genau das wundert mich auch, es funkioniert aber jetzt tadellos mit + .Ich wollt euch den Code eigentlich nicht zumuten, da ich dachte es sei vielleicht ein logisches Problem, aber wer dran interressiert ist :

          #!/usr/bin/perl -w

          $verzeichnis = '.';

          print "Content-type:text/html\n\n";
          .
          .
          .
          .
          .

          print "<title>memberlist</title>\n";
          print "</head>\n<body link="yellow" vlink="yellow">\n";
          print "<table width=100% border="0">\n";

          opendir(DIR, "$verzeichnis") or die "Verzeichnis kann nicht geoeffnet werden : $!\n";
             while ($file = readdir(DIR))  {
                if ($file =~ /^\d+.html/)   {
                push @unsortierte_liste, $file;
                }
             }
             closedir DIR;
             @dateiliste = sort { $a cmp $b } @unsortierte_liste;
             $i = 0;
             $i2 = 0;
             $anzahl_elemente = @dateiliste;

          foreach $file(@dateiliste)  {
               $i++;
               $i2++;
               open(DATEI,"$verzeichnis/$file") or die "Cant open memberlist: $!\n";
               @daten = <DATEI>;
                  foreach $zeile(@daten)  {
                      if ($zeile =~ /<font>MEMBER :</font></td><td align="left">(.*)</td></tr>/)  {
                         $eldnick = $1;
                      }
                  }
               if ($i == 1)  {
               print "<tr>\n";
               print "<td align="center"><a href="$file">$eldnick</a></td>\n";
                  if ($i2 == $anzahl_elemente)  {
                  print "</tr>\n";
                  }
               }

          if ($i == 2)  {
               print "<td align="center"><a href="$file">$eldnick</a></td>\n";
                  if ($i2 == $anzahl_elemente)  {
                  print "</tr>\n";
                  }
               }

          if ($i == 3)  {
               print "<td align="center"><a href="$file">$eldnick</a></td>\n";
               print "</tr>\n";
               $i = 0;
               }
               }
          close DATEI;
          print "</table>\n";
          print "</body>\n</html>\n";

          1. Hoi,

            #!/usr/bin/perl -w

            use strict;

            $verzeichnis = '.';

            my $verzeichnis = '.';

            print "<title>memberlist</title>\n";
            print "</head>\n<body link="yellow" vlink="yellow">\n";
            print "<table width=100% border="0">\n";

            print <<HTML;
            <html>
             <head>
              <title>Member list</title>
             </head>
             <body link="yellow" vlink="yellow">
            HTML

            opendir(DIR, "$verzeichnis") or die "Verzeichnis kann nicht geoeffnet werden : $!\n";
               while ($file = readdir(DIR))  {
                  if ($file =~ /^\d+.html/)   {
                  push @unsortierte_liste, $file;
                  }
               }
               closedir DIR;
               @dateiliste = sort { $a cmp $b } @unsortierte_liste;

            my @dateiliste = sort { $a cmp $b } grep(/^\d+.html$/,readdir DIR);

            $i = 0;
               $i2 = 0;
               $anzahl_elemente = @dateiliste;

            my .... ;-)

            Ich kann eigentlich nichts finden, was diesen Fehler verursachen koennte. Aber wie waere es
            mit use strict, use diagnostics? Vielleicht hilft dir das ja weiter.

            Gruss,
             CK

            1. Hallo

              Wie Christian schon sagte ist eigentlich kein Fehler zu entdecken, außer natürlich...
              die datei ".html" existiert wirklich.
              (kann zB passieren wenn ein Script, das dateien erstellen soll, nicht richtig funzt)
              Ist der fehler auf einem Server oder local aufgetreten?

              1. Hallo,

                Ist der fehler auf einem Server oder local aufgetreten?

                es war serverseitig, was ich dazusagen muss is, daß die .html Dateien, die ausgelesen wurden, jetzt aus der Unixzeit+.html bestehen, also 2435364635.html, oder so ähnlich ( vorher bestanden sie aus name.unixzeit.html, aber aus sortierungtechnischen Gründen habe ich es jetzt nur zu unixzeit.html geändert ).
                Vorher hatte ich 4 Dateien nach dem Schema name.unixzeit.html ,und wandte den reg. Ausdruck mit dem  *  drauf an, dabei entstand dieser merkwürdige Fehler. Das Script is sonst das gleiche.

                1. Auch hallo,

                  Ich vermute, daß irgendwann einmal bei Versuchen eine Datei namens '.html' erzeugt worden ist, Du sie aber nicht per FTP siehst, weil unter Unix Dateien mit führendem Punkt normalerweise nicht angezeigt werden, auch nicht von vielen FTP-Programmen. readdir liest aber alle Dateinamen ein.

                  Deshalb funktioniert /.+.html/ und nicht /.*.html/ aus bereits angeführten Gründen.

                  Grüße
                    Klaus

                  1. n'Abend Klaus !

                    Ich vermute, daß irgendwann einmal bei Versuchen eine Datei namens '.html' erzeugt worden ist, Du sie aber nicht per FTP siehst, weil unter Unix Dateien mit führendem Punkt normalerweise nicht angezeigt werden, auch nicht von vielen FTP-Programmen. readdir liest aber alle Dateinamen ein.

                    Müsste aber nicht auch /.+.html/ diese Datei auflisten ?
                    Der Ausdruck .html kommt ja schliesslich 1x vor. Oder wird
                    die Datei gefunden, weil der Ausdruck in /.*.html/ genau Null
                    mal vorkommt (ignoriert Perl versteckte Dateien?). Der zweite
                    Ausdruck müsste doch auch Dateien wie z.b: "html.xxxx" finden -
                    oder liege ich da falsch ?

                    Mc*dermitregexpsoseineliebenothat*Navc

                    1. Hallo McNavc!

                      Müsste aber nicht auch /.+.html/ diese Datei auflisten ?

                      nein. Der . steht für beliebiges Zeichen, das + dafür das es mindestens eins davon geben muss. Und das: .  meint den Punkt selber.
                      Also x.html => ja, ..html => ja aber .html eben nicht.

                      (ignoriert Perl versteckte Dateien?).

                      Nein, das ist IMHO Konvention, die von den gängigen GUIs und Shell-Tools beachtet wird.

                      Der zweite Ausdruck müsste doch auch Dateien wie z.b: "html.xxxx" finden -

                      nö. Er passt auch auf x.htmlHastenichtgesehen oder html.html.nix.
                      aber es muss mindestens ein bel. Zeichen, ein Punkt und dann das html vorkommen.

                      Wenn das .html am Ende stehen soll siehts so aus:
                      /.+.html$/
                       => mind. ein beliebiges Zeichen und am Ende .html

                      Gruss,
                       Carsten

                      1. n'Abend Carsten !

                        Alles klar - für den Moment wenigstens :-)

                        Wenn das .html am Ende stehen soll siehts so aus:
                        /.+.html$/
                        => mind. ein beliebiges Zeichen und am Ende .html

                        Und wenn ich richtig verstanden habe, ein $ und kein \b weil
                        sich seit Win95 Leerzeichen statt Unterstrich in Dateinamen
                        eingebürgert haben. /.+.html\b/ würde sonst auch auf
                        "keine.html datei.txt" passen ?

                        MfG McNavc

                        1. Hoi,

                          Wenn das .html am Ende stehen soll siehts so aus:
                          /.+.html$/
                          => mind. ein beliebiges Zeichen und am Ende .html

                          Und wenn ich richtig verstanden habe, ein $ und kein \b weil
                          sich seit Win95 Leerzeichen statt Unterstrich in Dateinamen
                          eingebürgert haben. /.+.html\b/ würde sonst auch auf
                          "keine.html datei.txt" passen ?

                          Oder auf "keine.html-datei.txt" oder auf "keine.html'datei.txt" ... usw.

                          Gruss,
                           CK

                          1. Morjen CK !

                            Oder auf "keine.html-datei.txt" oder auf "keine.html'datei.txt" ... usw.

                            Wenn ich dich richtig verstehe, so gilt nicht nur das Leerzeichen
                            bzw. das Zeilenende(?) als Wortgrenze, sondern jedes _nicht_
                            alphanumerische Zeichen ? Oder hab ich das mit dem \b falsch
                            verstanden ?

                            MfG McNavc

                            1. Hoi,

                              Oder auf "keine.html-datei.txt" oder auf "keine.html'datei.txt" ... usw.

                              Wenn ich dich richtig verstehe, so gilt nicht nur das Leerzeichen
                              bzw. das Zeilenende(?) als Wortgrenze, sondern jedes _nicht_
                              alphanumerische Zeichen ? Oder hab ich das mit dem \b falsch
                              verstanden ?

                              Das kann man so nicht sagen. \b passt auf Uebergaenge zwischen \w und \W, also

                              [0-9A-Za-z_] und [^0-9A-Za-z_]

                              Gruss,
                               CK

                              1. Tagchen CK !

                                Nachdem ich jetzt nach deinem Hinweis auf \w und \W zwei Perl
                                Docus "crossgelesen" hab, sind mir einige Lichter aufgegangen :)

                                Da wurde von [0-9A-Za-z_] als "Wortzeichen" und von [^0-9A-Za-z_]
                                als "keine Wortzeichen" gesprochen. Da bekommt der Begriff
                                "Wortgrenze" dann doch eine andere Bedeutung und mir wurde
                                klar, was du mit "Übergängen" zwischen \w und \W gemeint hast.

                                So, nachdem (für den Moment) alle Klarheiten beseitigt sind,
                                werd ich wieder mal ein bisschen mit RegExp herumprobieren.

                                Danke für die Unterstützung ! [1]

                                MfG McNavc

                                [1]natürlich an alle ! Und nicht zuletzt an xNeTworKx, der
                                mit seiner Ausgangsfrage mein Interesse an RegExp wieder
                                geweckt hat.

                                ps: wie wärs mit einer eindeutschung von RegExp, etwa RegAus ;-)

                                1. Hoi,

                                  Da wurde von [0-9A-Za-z_] als "Wortzeichen" und von [^0-9A-Za-z_]
                                  als "keine Wortzeichen" gesprochen. Da bekommt der Begriff
                                  "Wortgrenze" dann doch eine andere Bedeutung und mir wurde
                                  klar, was du mit "Übergängen" zwischen \w und \W gemeint hast.

                                  Ok, wollen wir mal ein wenig pruefen ;-) Was ist die Ausgabe des folgenden
                                  Scripts?:

                                  #!/usr/bin/perl -w

                                  use strict;
                                  my $str = 'blah blub blah';

                                  if($str =~ /blah(\b)blub/)
                                   {
                                    print "'",$1,"'\n";
                                   }

                                  (Achtung! Fangfrage >;)

                                  ps: wie wärs mit einer eindeutschung von RegExp, etwa RegAus ;-)

                                  Und die User heissen dann 'RegDaus'? *g*

                                  Gruss,
                                   CK

                                  1. Tagchen CK !

                                    Ok, wollen wir mal ein wenig pruefen ;-) Was ist die Ausgabe des folgenden
                                    Scripts?:

                                    Der Eingabeprompt.

                                    Mal sehen ob ich's auch richtig interpretiere:
                                    $1 würde die "Wortgrenze" enthalten. Da das aber natürlich nichts
                                    ist das man irgendwie als string verarbeiten kann ist natürlich
                                    auch die if-Abfrage false. Okay, ist jetzt von hinten herum
                                    beschrieben :)

                                    Mit \W statt \b müsste ich allerdings das Leerzeichen zwischen
                                    blah und blub erhalten.

                                    MfG McNavc

                                    1. Hoi,

                                      Der Eingabeprompt.

                                      Genau richtig - hast du es zuerst ausprobiert oder zuerst ueberlegt? ;-)

                                      Mal sehen ob ich's auch richtig interpretiere:
                                      $1 würde die "Wortgrenze" enthalten. Da das aber natürlich nichts
                                      ist das man irgendwie als string verarbeiten kann ist natürlich
                                      auch die if-Abfrage false. Okay, ist jetzt von hinten herum
                                      beschrieben :)

                                      Jepp. \b ist kein Zeichen, nur ein Modifier. Aehnlich wie \Q und \E. Aber trotzdem
                                      ist es nicht ganz richtig. Wie gesagt, \b ist kein Zeichen, deshalb matcht es nicht auf
                                      den Space zwischen 'blah' und 'blub'. Deshalb wird auch der Teil im If gar nicht erst
                                      ausgefuehrt.

                                      Mit \W statt \b müsste ich allerdings das Leerzeichen zwischen
                                      blah und blub erhalten.

                                      Jupp.

                                      Gruss,
                                       CK

                                      1. Hoi,

                                        Tach,

                                        \b ist kein Zeichen, nur ein Modifier.

                                        \b ist kein Modifier, sondern ein Anker.

                                        Aehnlich wie \Q und \E.

                                        Nein, das ist etwas völlig anderes.

                                        Jens

                                      2. n'Abend CK !

                                        Genau richtig - hast du es zuerst ausprobiert oder zuerst ueberlegt? ;-)

                                        *unschuldigguckundpfeif* na ja, mein erster Gedanke war (natürlich
                                        ohne nachzudenken): das Leerzeichen. Kam mir dann aber komisch vor,
                                        weil \b ja nicht wirklich mit etwas übereinstimmt, sondern etwas
                                        begrenzt. Da kam mir dann die Idee mit dem \W, die ich ausprobiert
                                        habe - und bei der Gelegenheit natürlich auch deine Version ;-)

                                        Nachdem ich dann das Ergebniss hatte war's eigentlich recht einfach
                                        die Begründung dafür zu finden.

                                        MfG McNavc

                                        1. Hoi,

                                          Du solltest dir btw. bei Gelegenheit mal das Buch

                                          "Mastering Regular Expressions"

                                          oder auf Deutsch

                                          "Regulaere Ausdruecke"

                                          zulegen. Das kann ich nur empfehlen ;-) Leider konnte ich bisher auch nur gelegentlich
                                          reinschauen.

                                          Gruesse,
                                           CK

                                          1. Tagchen CK !

                                            "Mastering Regular Expressions"

                                            Bevor ich Google bemühe <p style="unverschämt">
                                            Hast du zufällig Verlag und/oder ISBN Nummer bei der Hand ?</p>

                                            MfG McNavc

                                            1. Hallo McNavc!

                                              Hast du zufällig Verlag und/oder ISBN Nummer bei der Hand ?

                                              http://www.oreilly.com/catalog/regex/

                                              wo sonst?

                                              Gruss,
                                               Carsten

                                              1. Tagchen Carsten !

                                                Ich hätt mir's eigentlich denken können ;-)

                                                Danke !

                                                MfG McNavc

                    2. Hi,

                      Müsste aber nicht auch /.+.html/ diese Datei auflisten ?

                      nein, denn mit .+ sagst du "mindestens ein beliebiges zeichen vor .html"
                      heisst die datei nun ".html" steht _kein_ zeichen davor, damit ist o.g. muster nicht erfüllt

                      Der Ausdruck .html kommt ja schliesslich 1x vor. Oder wird
                      die Datei gefunden, weil der Ausdruck in /.*.html/ genau Null
                      mal vorkommt (ignoriert Perl versteckte Dateien?).

                      langsam verstehe ich, daß da ein grundlegendes verständnissproblem vorliegt..
                      ein + oder ein * bezieht sich nur auf das genau davor stehende zeichen
                      (oder die davor stehende, in klammern gesetzte grupierung, aber das ist für dein beispiel irrelevant)
                      und nicht auf das ganze oder nachfolgende muster.

                      das Zeichen "." hat nun die besondere bedeutung "beliebiges Zeichen" (naja fast, aber die besonderheit ist momentan irrelevant, ggf. nachlesen) also entspricht ".*" ungefähr dem "*" unter z.B. DOS.

                      Der zweite
                      Ausdruck müsste doch auch Dateien wie z.b: "html.xxxx" finden -
                      oder liege ich da falsch ?

                      nein (müsste er nicht finden), da .* somit (s.o.) besagt "eine beliebige Anzahl beliebiger Zeichen (einschließlich kein Zeichen) _vor_ ".html".
                      Über die Zeichen dahinter triffst du zwar keine Aussage, aber es fehlt der in deinem Muster durch . verlangte "." vor "html.xxxx". Er würde allerdings ".html.xxxx" finden.
                      (durch den "" in "." sagst du, daß du tatsächlich den "." als Zeichen meinst und nicht in seiner Bedeutung als Platzhalter für ein "beliebiges Zeichen".)

                      Grüße,
                      Marcus

                      1. n'Abend Marcus

                        langsam verstehe ich, daß da ein grundlegendes verständnissproblem vorliegt..

                        Du sagst es. Ich habe zwar .+ gesehen, aber irgendwie ist
                        mir die Bedeutung am Weg vom Auge zum Hirn bzw. zum Verstehen
                        verlorengegangen :( Da kam nur mehr das "html" und 1 oder mehr
                        mals für das + an.

                        MfG McNavc

      2. Hallo!

        Korrektur: In selfhtml war es falsch beschrieben:

        • + Das Pluszeichen steht ansonsten für kein, ein oder mehrmaliges Vorkommen des davorstehenden Zeichens. /\d+\d/
          * \* Das Sternzeichen steht ansonsten für ein oder mehrmaliges Vorkommen des davorstehenden Zeichens. /\*char/

        Die Onlineversion ist mittlerweile korrigiert
        http://selfhtml.teamone.de/cgiperl/sprache/regexpr.htm#maskierung

        Adios

        1. Hi Tom!

          Die Onlineversion ist mittlerweile korrigiert
          http://selfhtml.teamone.de/cgiperl/sprache/regexpr.htm#maskierung

          Dann solltest Du das mit Deiner Offline-Version vielleicht auch machen: http://aktuell.de.selfhtml.org/extras/download.shtml#a3 ganz unten.

          So long