2010-12-28 11 views
4

Ich versuche, eine Liste von Dateien zu suchen und arbeiten nur an den Dateien, die Namen haben, die ein paar Werte in einem Array enthalten. Ich hoffe, ich muss das Array nicht jedes Mal durchlaufen, wenn ich einen neuen Dateinamen habe.
ala-Suchzeichenfolge mit Array von Werten mit PHP

$needle = array('blah', 'bleh'); 
foreach($file_list as $file) 
{ 
    foreach($needle as $need) 
     if(strstr($file, $need) !== false) 
      { 
      // do something... 
      } 
} 

Ich muss nur wissen, ob eines der Strings in dem Array im Dateinamen, nicht die Position der Zeichenfolge.

Ich möchte etwas ähnliches wie strstr() verwenden, aber es erlaubt nicht ein Array als die Nadel verwendet werden.

i.e.-

if(strstr($haystack, array('blah', 'bleh'))) 
{ 
    // do something... 
} 

Ich würde von regulären Ausdrücken bleiben lieber weg, so scheint es, ein Schlitten für einen Hammer Job zu sein. irgendwelche Ideen?

+0

verwenden ein 'brechen 2;', wenn Sie das erste Vorkommen finden http://php.net/manual/en/control-structures.break.php – s3v3n

+0

tatsächlich das Problem, dass Sie don‘ Willst du das gesamte Array loopen oder ein Array als Nadel nicht passieren? – s3v3n

+0

Ich möchte nicht durch das Array durchlaufen, und ich kann nicht die Nadel als ein Array zu 'strstr()' – Patrick

Antwort

6

IMO es ist in Ordnung hier reguläre Ausdrücke zu verwenden:

$pattern = '/' . implode('|', array_map('preg_quote', $needle)) . '/i'; 

foreach($file_list as $file) { 
    if(preg_match($pattern, $file)) { 
    // do something 
    } 
} 

Referenz: preg_quote


Hier ein "kreativer" Weg, es zu tun (aber es verwendet interne Schleifen und ist sehr wahrscheinlich langsamer, als Sie Schleife tatsächlich mehrmals über das Array):

function cstrstr($haystack, $needle) { 
    return strstr($haystack, $needle) !== false; 
} 

foreach($file_list as $file) { 
    if(array_sum(array_map('cstrstr', 
         array_pad(array($file), count($needle), $file), 
         $needle))) { 
     // do something 
    } 
} 

Aber die Vorteile mit der Regex offensichtlich sein sollte: Sie haben das Muster nur einmal während in der „lustigen“ Lösung erstellen Sie müssen immer ein Array der Länge count($needle) für jede $file erstellen.

+0

Warum Regex verwenden, wenn es einfach ist, 'strstr()' oder 'in_array()' zu verwenden? es wird die Komplexität des Algorithmus erhöhen. – s3v3n

+0

@ s3v3n: Ja, du kannst eine Schleife machen und 'strstr()' verwenden und brechen, wenn du sie gefunden hast. Das ist eine andere Lösung. Aber 'in_array' funktioniert nur, wenn der Name der Datei * gleich * zu einem Wort im Array ist. Ich habe die Frage verstanden, wie der Dateiname * Wörter im Array enthalten kann ... –

+0

Eigentlich habe ich eine Idee. Ich werde es jetzt als Antwort posten. – s3v3n

1

Patrick,

Sie können in_array() verwenden. Beispiel:

foreach($file_list as $file){ 

    if(in_array($file, $needle)){ 
    //-------------- 
    // Needle found 
    } 
} 

Sie können weitere Beispiele finden Sie hier: http://php.net/manual/en/function.in-array.php

+0

Ich versuche nicht, den gesamten Dateinamen obwohl, funktioniert 'in_array()' arbeiten auf Teilstrings auch? – Patrick

+0

@Patrick: Nein, tut es nicht. –

+0

@Patrick, könnten Sie ein Beispiel für die Dateinamen angeben, mit denen Sie arbeiten? Es ist möglicherweise einfacher, eine bestimmte Namenskonvention auf Ihre Dateien anzuwenden, damit in_array() korrekt funktioniert. Wenn Sie das Ziel haben, das Array nicht jedes Mal zu durchlaufen, ist in_array() der beste Weg. –

0

in_array kann gut funktionieren, aber es würde genaue Übereinstimmungen in Ihrem Nadelarray erfordern.

Sie könnten das Array mit einigen Hash-String implode, und verwenden Sie das Ergebnis mit strstr oder strpos - str Variante gibt das erste Auftreten, pos nur die Position des ersten occurrence- Achten Sie auf eine sehr eindeutige Zeichenfolge haben, mit beides ein ungewöhnliches Präfix und Suffix. Dies ist eher ein schneller und dreckiger Ansatz, aber es kann nur in Ihrer Situation funktionieren.

EDIT Ich dachte nur, warum willst du nicht eine Schleife verwenden? Es wird viel schneller sein als das Verketten aller Elemente eines Arrays.Ihre Frage, ob es eine Funktion gibt, um partielle Übereinstimmungen mit einem Referenzarray zu finden: Es ist nicht eingebaut, also verwenden Sie besser Ihre eigene Schleife (oder implementieren Sie eine Funktion, natürlich mit einer Schleife)

+0

Wie würden Sie einen Hash-String verwenden, um das zu machen? – Patrick

+0

Nehmen wir an, Sie haben 'arrray ('somevalue1', 'somevalue2')' und die Datei 'value1'. Die Verwendung von 'implode' mit' :: 'würde' somevalue1 :: somevalue2' und dann 'strpos ($ imploded_array, 'value1')' würde nicht-FALSE zurückgeben. – Joost

1

Dies wird eine Aktion für alle Dateien durchführen, die

// Loop through files 
foreach($files as $file){ 
    foreach($needles as $needle){ 
     // if filename does not contain this needle 
     if(strpos($file, $needle) === false) 
      continue 2; // skip to next file 
    } 
    // this file matches criteria. do smth on this file 
} 
0
if(strstr(implode(" ", $array), $search) { //found } 

Aber eine Funktion mit Schleife in ihrem Namen alle Nadeln enthalten und zurück, wenn festgestellt wird schneller und weniger Speicher verbrauchen.

Funktion searchArrayFast ($ array, $ search) { foreach ($ array wie $ a) { if (strstr ($ A, $ search)) { return true; } } Rückgabe false; }

0

Verwenden Sie nicht preg_match(), wenn Sie nur überprüfen möchten, ob eine Zeichenfolge in einer anderen Zeichenfolge enthalten ist. Verwenden Sie stattdessen strpos(), da es schneller ist. http://php.net/manual/en/function.preg-match.php

$needle = array('blah', 'bleh'); 

foreach ($file_list as $file) { 

    $result = $this->searchStrpos($file, $needle); 

     if ($result !== false) { 

      // do something... 
     } 
    } 

/** 
* 
* @param String $string String search 
* @param mixed $needle 
* @param Boolean $onlyFirst return true but 
* @return Boolean Return boolean for search 
*/ 
private function searchStrpos($string, $needle, $onlyFirst = true) { 
    if (is_array($needle)) { 
     foreach ($needle as $item) { 
      $result = strpos($string, $item); 
      if ($result !== false && $onlyFirst) { 
       break; 
      } 
     } 
    } else { 
     $result = strpos($string, $needle); 
    } 

    return $result; 
} 
Verwandte Themen