Ankündigung

Einklappen
Keine Ankündigung bisher.

Dateinamen auflisten und nur Dateien mit bestimmtem Muster behalten

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Dateinamen auflisten und nur Dateien mit bestimmtem Muster behalten

    Hallo zusammen,

    ich würde gerne eine Aufgabe mittels PHP lösen. Hierfür muss jeder Dateiname aus einem Ordner in ein Array geschrieben werden. Das sollte kein Problem sein (scandir).

    Die Dateinamen sind folgendermaßen aufgebaut:

    titel123.png
    titel123-150x150.png
    titel123-250x250.png

    Ich möchte nun nur die Dateinamen behalten, die keine Maßangabe beinhalten, also in diesem Falle nur "titel123.png".

    Das Problem ist: Die Maßangabe variiert stark. Mann erkennt diese also nur an ...x... .png am Ende.

    Wie komme ich an ein Array, welches nur die gewünschten Dateinamen enthält?

  • #2
    Da gibt es verschiedene Möglichkeiten. Der "generische" Weg, Elemente aus einem Array zu filtern ist array_filter():
    PHP-Code:
    array_filter(
        
    $filenames,
        function (
    $basename) {
            return !
    preg_match('/[0-9]+x[0-9]+\.[a-z]+\z/'$basename);
        }
    ); 
    Für Filterung ausschließlich mit PCRE geht das noch einfacher:
    PHP-Code:
    preg_grep('/[0-9]+x[0-9]+\.[a-z]+\z/'$filenamesPREG_GREP_INVERT); 
    Falls du die Dateinamen ausschließlich in einer foreach-Schleife abarbeiten möchtest, kannst du dir auch einen Generator basteln. Der hat den (kleinen) Vorteil, dass für nicht benötigte Dateinamen gar nicht erst ein Array-Eintrag erstellt werden muss.

    PHP-Code:
    function traverse_and_filter_dir($dirpath$filter '//'$invert false) {
        if (!
    is_resource($dir opendir($dirpath))) {
            return;
        }
        
    $pwd getcwd();
        if (!
    chdir($dirpath)) {
            
    closedir($dir);
            return;
        }
        
    $invert $invert || PREG_GREP_INVERT === $invert 0;
        while (
    $item readdir($dir)) {
            if (
    is_dir($item)) {
                continue;
            }
            if (
    $invert === preg_match($filter$item)) {
                continue;
            }
            yield 
    $item;
        }
        
    chdir($pwd);
        
    closedir($dir);
        return;

    Die Anwendung ist einfacher:

    PHP-Code:
    $dirpath '.';
    $filter '/[0-9]+x[0-9]+\.[a-z]+\z/';
    foreach (
    traverse_and_filter_dir($dirpath$filterPREG_GREP_INVERT) as $file_basename) {
        
    var_dump($file_basename);

    Kommentar


    • #3
      PHP-Code:
      $itDirIterator = new DirectoryIterator'verzeichnis/das/du/durchsuchen/willst/' );
      $itRxIterator = new RegexIterator$itDirIterator'/titel[\d]+\.png/i'RegexIterator::ALL_MATCHES );

      print_riterator_to_array($itRxIterator) ); 

      Kommentar


      • #4
        Der Vollständigkeit halber sei noch der GlobIterator erwähnt.

        Kommentar


        • #5
          Zitat von fireweasel Beitrag anzeigen
          Da gibt es verschiedene Möglichkeiten. Der "generische" Weg, Elemente aus einem Array zu filtern ist array_filter():
          PHP-Code:
          array_filter(
          $filenames,
          function (
          $basename) {
          return !
          preg_match('/[0-9]+x[0-9]+\.[a-z]+\z/'$basename);
          }
          ); 
          Für Filterung ausschließlich mit PCRE geht das noch einfacher:
          PHP-Code:
          preg_grep('/[0-9]+x[0-9]+\.[a-z]+\z/'$filenamesPREG_GREP_INVERT); 
          Falls du die Dateinamen ausschließlich in einer foreach-Schleife abarbeiten möchtest, kannst du dir auch einen Generator basteln. Der hat den (kleinen) Vorteil, dass für nicht benötigte Dateinamen gar nicht erst ein Array-Eintrag erstellt werden muss.

          PHP-Code:
          function traverse_and_filter_dir($dirpath$filter '//'$invert false) {
          if (!
          is_resource($dir opendir($dirpath))) {
          return;
          }
          $pwd getcwd();
          if (!
          chdir($dirpath)) {
          closedir($dir);
          return;
          }
          $invert $invert || PREG_GREP_INVERT === $invert 0;
          while (
          $item readdir($dir)) {
          if (
          is_dir($item)) {
          continue;
          }
          if (
          $invert === preg_match($filter$item)) {
          continue;
          }
          yield 
          $item;
          }
          chdir($pwd);
          closedir($dir);
          return;

          Die Anwendung ist einfacher:

          PHP-Code:
          $dirpath '.';
          $filter '/[0-9]+x[0-9]+\.[a-z]+\z/';
          foreach (
          traverse_and_filter_dir($dirpath$filterPREG_GREP_INVERT) as $file_basename) {
          var_dump($file_basename);

          Hallo und vielen Dank an alle für eure Hilfe.

          Bei der o.g. Anwendung erhalte ich die Meldung:

          PHP Parse error: syntax error, unexpected '$item' (T_VARIABLE) in gen.php on line 19
          line 19 ist

          PHP-Code:
          yield $item

          Kommentar


          • #6
            yield und Generatoren gibt es erst ab PHP 5.5.*

            Kommentar


            • #7
              Schade. Auf dem Server läuft 5.4.39.

              Ich habe nun folgenden Ablauf:

              PHP-Code:
              <?php

              $dir 
              '/uploads';
              $filenames scandir($dir);
              //var_dump($filenames);

              array_filter(
                  
              $filenames,
                  function (
              $basename) {
                      return !
              preg_match('/[0-9]+x[0-9]+\.[a-z]+\z/'$basename);
                  }
              );

              var_dump($filenames); 


              ?>
              Ich bekomme als Ergebnis allerdings weiterhin auch Bilder mit Größenangabe:

              [30]=>
              string(39) "Test1813-150x150.jpg"
              [31]=>
              string(39) "Test1813-175x116.jpg"
              [32]=>
              string(39) "Test1813-329x219.jpg"
              [33]=>
              string(39) "Test1813-899x198.jpg"
              [34]=>
              string(31) "Test1813.jpg"

              Kommentar


              • #8
                Hast Du mal #3 probiert?

                Kommentar


                • #9
                  Hi Arne,

                  ja, allerdings beginnen nicht alle Dateien mit "titel".

                  Das Ergebnis ist folgendes:

                  [1] => Array
                  (
                  [0] => Array
                  (
                  [0] => 100.jpg
                  )

                  )

                  ...


                  Also habe ich hier nicht die Ergebnisse, die ich eigentlich wollte...

                  Ich habe auch folgendes einmal probiert:

                  PHP-Code:
                  <?php

                  $dir 
                  '/uploads';
                  $filenames scandir($dir);

                  $files preg_grep('/[0-9]+x[0-9]+\.[a-z]+\z/'$filenamesPREG_GREP_INVERT);

                  var_dump($files);

                  ?>
                  Das funktioniert scheinbar auch nicht ganz, denn ich erhalte zwar auch korrekte Ergebnisse wie


                  [55]=>
                  string(16) "testbild.jpg"
                  aber leider auch solche Ergebnisse:

                  string(15) "jpg97-230x1024."
                  [31]=>

                  Kommentar


                  • #10
                    ja, allerdings beginnen nicht alle Dateien mit "titel".
                    Ja nun, dann passt Du den RegEx-Pattern halt an:
                    Code:
                    /[a-z\d]+\.png/i
                    ein bisschen selbst Mitdenken solltest Du schon...

                    Kommentar


                    • #11
                      Hi Arne,

                      ich bin mit regulären Ausdrücken noch gar nicht vertraut. Ich lese gerade parallel etwas dazu, aber zum richtigen Ergebnis komme ich da noch nicht.

                      Korrekt wäre dann $files = preg_grep('/[a-z\d]+\.png/i', $filenames, PREG_GREP_INVERT); ?

                      Kommentar


                      • #12
                        Den Invert-Parameter kann man beim RegexIterator leider nicht anwenden.
                        Daher musst Du das Pattern anpassen...


                        EDIT
                        Habe mir mal ein Verzeichnis mit drei Bildern angelegt:
                        Code:
                        foobar.png
                        foobar123.png
                        foobar-123x456.png
                        und erhalte mit dem folgenden Zweizeiler ( Ausgabe nicht mitgezählt ):
                        PHP-Code:
                        $d = new DirectoryIterator'./' );
                        $x = new RegexIterator$d'/^[a-z\d]+\.png$/i'RegexIterator::GET_MATCH );


                        print_riterator_to_array($x) ); 
                        diese Ausgabe:
                        Code:
                        Array
                        (
                            [0] => Array
                                (
                                    [0] => foobar123.png
                                )
                        
                             [1] => Array
                                (
                                    [0] => foobar.png
                                )
                        )

                        Kommentar


                        • #13
                          Sehr cool Danke, das scheint zu funktionieren. Wenn ich nun png und jpg ausgeben möchte - wie kann ich das umsetzen?

                          Kommentar


                          • #14
                            Code:
                            /^[a-z\d]+\.(png|jpg)$/i

                            Kommentar


                            • #15
                              Zitat von SPQR Inc. Beitrag anzeigen
                              [/PHP]

                              Das funktioniert scheinbar auch nicht ganz, denn ich erhalte zwar auch korrekte Ergebnisse wie
                              ...
                              aber leider auch solche Ergebnisse:
                              Code:
                              string(15) "jpg97-230x1024."
                              Dafür kann preg_grep() aber nichts. Wer generiert denn solche Dateinamen?
                              Man kann zwar den Regex dafür anpassen, ...
                              Code:
                              '/[0-9]+x[0-9]+/'
                              (mit PREG_GREP_INVERT)
                              Code:
                              '/\A([^x]|(?<![0-9])x(?![0-9]))+\z/'
                              (ohne PREG_GREP_INVERT)
                              ... aber besser wäre es, gleich Dateinamen in der Form zu erzeugen, an die wir gewöhnt sind. Windows (das ganze Betriebssystem) bspw. kann damit gar nicht umgehen.



                              Kommentar

                              Lädt...
                              X