2010-02-21 45 views
7

C'è un modo per inserire un carattere jolly in una stringa? Il motivo per cui lo chiedo è perché attualmente ho una funzione per cercare una sottostringa tra due sottostringhe (ad esempio, prendi il contenuto tra "my" e "has fleas" nella frase "my dog ​​has fleas", risultante in "dog").Stringa di ricerca php (con caratteri jolly)

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); 
} 

Quello che voglio fare è cercarlo con un carattere jolly nella stringa. Quindi dì che cerco tra "% WILDCARD%" e "has fleas" nella frase "My dog ​​has fleas" - uscirà comunque "dog".

Non so se l'ho spiegato troppo bene, ma spero che qualcuno mi capisca: P. Grazie mille per la lettura!

+1

se si vuole i caratteri jolly, è possibile utilizzare le espressioni regolari, invece. – ghostdog74

+0

grazie mille ragazzi, davvero! – Baehr

risposta

8

Questo è uno dei pochi casi in cui le espressioni regolari sono effettivamente utili. :)

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

Vedere la documentazione per preg_match.

+10

Questo è solo ignorante, le espressioni regolari sono strumenti eccellenti. – raveren

+0

@Raveren: le espressioni regolari sono strumenti terribili nella mano degli sciocchi. Il modo in cui molte persone li usano senza capire i loro limiti, che tipo di motori esistono, ecc. – Christian

+15

* Le espressioni regolari sono strumenti terribili nella mano dei matti. * Quindi è letteralmente ogni altro strumento esistente. – raveren

2

Utilizzare un'espressione regolare.

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

\S significa qualsiasi carattere non-spazio, + significa una o più della cosa precedente, in modo da \S+ significa partita uno o più caratteri non spaziali. (…) significa acquisire il contenuto della submatch e inserirlo nell'array $matches.

0

Se si desidera utilizzare il carattere jolly (e sì, PREG è molto meglio) è possibile utilizzare la funzione fnmatch che funziona solo su * NIX.

Acclamazioni

3

Sono d'accordo che regex sono molto più flessibile di caratteri jolly, ma a volte tutto quello che volete è un modo semplice per definire modelli. Per le persone in cerca di una soluzione portatile (non * NIX solo) ecco la mia implementazione della funzione:

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; 
} 

Naturalmente l'attuazione PHP è più lento di fnmatch(), ma dovrebbe funzionare su qualsiasi piattaforma.

Può essere usato così:

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

bello! avevamo il requisito di consentire al nostro personale di inserire regole di espressione regolari per abbinare determinati dati. Poiché non capiscono regex, questa era la soluzione perfetta! – Luc

1

carattere jolly potrebbe essere convertito in regex simili

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

se contenuto della stringa caratteri speciali, ad esempio .? \ + *^$ | {}/'#, Dovrebbero essere \ -escaped

non testato:

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

Dovrebbe essere possibile un preg_quote arround al modello $ – velop

Problemi correlati