2010-02-21 5 views
7

Existe-t-il un moyen de placer un caractère générique dans une chaîne? La raison pour laquelle je demande est parce que j'ai actuellement une fonction pour rechercher une sous-chaîne entre deux sous-chaînes (à savoir saisir le contenu entre "mon" et "a des puces" dans la phrase "mon chien a des puces").Chaîne de recherche Php (avec caractères génériques)

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

Ce que je veux faire est de le faire rechercher avec un caractère générique dans la chaîne. Donc disons que je cherche entre "% WILDCARD%" et "a des puces" dans la phrase "Mon chien a des puces" - il produirait toujours "chien".

Je ne sais pas si je l'ai bien expliqué mais j'espère que quelqu'un me comprendra: P. Merci beaucoup d'avoir lu!

+1

si vous voulez des jokers, vous pouvez utiliser des expressions régulières au lieu. – ghostdog74

+0

merci beaucoup les gars, vraiment! – Baehr

Répondre

8

Ceci est l'un des rares cas où les expressions régulières sont réellement utiles. :)

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

Voir la documentation de preg_match.

+10

C'est juste ignorant, les expressions régulières sont d'excellents outils. – raveren

+0

@Raveren: Les expressions régulières sont des outils terribles dans la main des imbéciles. Beaucoup de gens les utilisent sans comprendre leurs limites, quels types de moteurs existent, etc. – Christian

+15

* Les expressions régulières sont des outils terribles dans la main des imbéciles. * Donc, littéralement, tous les autres outils existent. – raveren

2

Utilisez une regex.

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

\S signifie tout caractère non espace, + signifie un ou plusieurs de la chose précédente, donc \S+ signifie correspondre à l'un ou plusieurs caractères non-espace. (…) signifie capturer le contenu du submatch et le placer dans le tableau $matches.

0

Si vous insistez pour utiliser un caractère générique (et oui, PREG est beaucoup mieux), vous pouvez utiliser la fonction fnmatch qui fonctionne uniquement sur * NIX.

Vive

3

Je suis d'accord que sont regex beaucoup plus souples que les jokers, mais parfois tout ce que vous voulez est un moyen simple de définir des modèles. Pour les personnes à la recherche d'une solution portable (non * NIX uniquement) voici ma mise en œuvre de la fonction:

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

Naturellement, la mise en œuvre de PHP est plus lent que fnmatch(), mais il travaillerait sur toute plate-forme.

Il peut être utilisé comme ceci:

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

sympa! nous avions l'obligation de permettre à notre personnel d'entrer des règles d'expression régulières pour faire correspondre certaines données. Comme ils ne comprennent pas regex, c'était la solution parfaite! – Luc

1

modèle générique pourrait être converti en modèle regex comme celui-ci

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

si contenu de la chaîne des caractères spéciaux, par exemple .? \ + *^$ | {}/'#, Ils devraient être \ encodée

ne pas testé:

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

Il devrait être possible de faire une preg_quote au motif $ – velop

Questions connexes