2010-02-21 1 views
7

Gibt es eine Möglichkeit, einen Platzhalter in eine Zeichenfolge einzufügen? Der Grund, warum ich frage, ist, weil ich derzeit eine Funktion habe, um nach einem Teilstring zwischen zwei Teilstrings zu suchen (dh den Inhalt zwischen "mein" und "hat Flöhe" im Satz "mein Hund hat Flöhe"), was zu "Hund" führt).PHP-Suchzeichenfolge (mit Platzhaltern)

function get_string_between($string, $start, $end){ 
    $string = " ".$string; 
    $ini = strpos($string,$start); 
    if ($ini == 0) return ""; 
    $ini += strlen($start); 
    $len = strpos($string,$end,$ini) - $ini; 
    return substr($string,$ini,$len); 
} 

Was ich tun möchte, ist es mit einem Platzhalter in der Zeichenfolge zu suchen. Also sag ich suche zwischen "% WILDCARD%" und "hat Flöhe" im Satz "Mein Hund hat Flöhe" - es würde immer noch "Hund" ausgeben.

Ich weiß nicht, ob ich es zu gut erklärt habe, aber hoffentlich versteht mich jemand: P. Vielen Dank fürs Lesen!

+1

wenn Sie Platzhalter möchten, können Sie stattdessen reguläre Ausdrücke verwenden. – ghostdog74

+0

vielen Dank Jungs, wirklich! – Baehr

Antwort

8

Dies ist einer der wenigen Fälle, in denen reguläre Ausdrücke hilfreich sind. :)

if (preg_match('/my (\w+) has/', $str, $matches)) { 
    echo $matches[1]; 
} 

Siehe Dokumentation für preg_match.

+10

Das ist einfach ignorant, reguläre Ausdrücke sind ausgezeichnete Werkzeuge. – raveren

+0

@Raveren: Reguläre Ausdrücke sind schreckliche Werkzeuge in der Hand von Narren. Way to viele Menschen nutzen sie ohne ihre Grenzen zu verstehen, welche Art von Motoren existieren usw. – Christian

+15

* Reguläre Ausdrücke sind schreckliche Werkzeuge in der Hand von Narren. * So ist buchstäblich jedes andere Werkzeug in Existenz. – raveren

2

Verwenden Sie eine Regex.

$string = "My dog has fleas"; 
if (preg_match("/\S+ (\S+) has fleas/", $string, $matches)) 
    echo ($matches[1]); 
else 
    echo ("Not found"); 

\S jede Nicht-Raumzeichen, + bedeutet eine oder mehreren der vorhergehenden Sache, so bedeutet \S+ Spiel ein oder mehr Nicht-Raumzeichen. (…) bedeutet, dass der Inhalt des Submatch erfasst und in das Array $matches eingegeben wird.

0

Wenn Sie darauf bestehen, Platzhalter zu verwenden (und ja, PREG ist viel besser), können Sie die Funktion fnmatch verwenden, die nur auf * NIX funktioniert.

Prost

3

Ich bin damit einverstanden, dass regex als Platzhalter viel flexibler sind, aber manchmal alles, was Sie Muster eine einfache Art und Weise definieren wollen. Für Menschen, für eine tragbare Lösung suchen (nicht * NIX nur) hier ist meine Implementierung der Funktion:

function wild_compare($wild, $string) { 
    $wild_i = 0; 
    $string_i = 0; 

    $wild_len = strlen($wild); 
    $string_len = strlen($string); 

    while ($string_i < $string_len && $wild[$wild_i] != '*') { 
     if (($wild[$wild_i] != $string[$string_i]) && ($wild[$wild_i] != '?')) { 
      return 0; 
     } 
     $wild_i++; 
     $string_i++; 
    } 

    $mp = 0; 
    $cp = 0; 

    while ($string_i < $string_len) { 
     if ($wild[$wild_i] == '*') { 
      if (++$wild_i == $wild_len) { 
       return 1; 
      } 
      $mp = $wild_i; 
      $cp = $string_i + 1; 
     } 
     else 
     if (($wild[$wild_i] == $string[$string_i]) || ($wild[$wild_i] == '?')) { 
      $wild_i++; 
      $string_i++; 
     } 
     else { 
      $wild_i = $mp; 
      $string_i = $cp++; 
     } 
    } 

    while ($wild[$wild_i] == '*') { 
     $wild_i++; 
    } 

    return $wild_i == $wild_len ? 1 : 0; 
} 

Natürlich ist die PHP-Implementierung ist langsamer als fnmatch(), aber es wäre auf jeder Plattform zu arbeiten.

Es kann wie folgt verwendet werden:

if (wild_compare('regex are * useful', 'regex are always useful') == 1) { 
    echo "I'm glad we agree on this"; 
} 
+0

nett! Wir hatten die Anforderung, unseren Mitarbeitern zu erlauben, Regeln für reguläre Ausdrücke einzugeben, um bestimmte Daten zu vergleichen. Da sie Regex nicht verstehen, war dies die perfekte Lösung! – Luc

1

Wildcard Muster RegexMuster umgewandelt werden könnten wie diese

function wildcard_match($pattern, $subject) { 
    $pattern = strtr($pattern, array(
    '*' => '.*?', // 0 or more (lazy) - asterisk (*) 
    '?' => '.', // 1 character - question mark (?) 
)); 
    return preg_match("/$pattern/", $subject); 
} 

wenn String Inhalt Sonderzeichen, zum Beispiel .? \ + *^$ | {}/'#, Sollten sie \ -escaped

sein getestet nicht:

function wildcard_match($pattern, $subject) { 
    // quotemeta function has most similar behavior, 
    // it escapes \.+*?^$[](), but doesn't escape |{}/'# 
    // we don't include * and ? 
    $special_chars = "\.+^$[]()|{}/'#"; 
    $special_chars = str_split($special_chars); 
    $escape = array(); 
    foreach ($special_chars as $char) $escape[$char] = "\\$char"; 
    $pattern = strtr($pattern, $escape); 
    $pattern = strtr($pattern, array(
    '*' => '.*?', // 0 or more (lazy) - asterisk (*) 
    '?' => '.', // 1 character - question mark (?) 
)); 
    return preg_match("/$pattern/", $subject); 
} 
+0

Es sollte eine preg_quote arround am $ -Muster möglich sein – velop