web-dev-qa-db-fra.com

chaîne php correspondant à un caractère générique *?

Je veux donner la possibilité de faire correspondre la chaîne avec le caractère générique *.

Exemple

$mystring = 'dir/folder1/file';
$pattern = 'dir/*/file';

stringMatchWithWildcard($mystring,$pattern);  //> Returns true

Exemple 2:

$mystring = 'string bl#abla;y';
$pattern = 'string*y'; 

stringMatchWithWildcard($mystring,$pattern);  //> Returns true

J'ai pensé quelque chose comme:

function stringMatch($source,$pattern) {
    $pattern = preg_quote($pattern,'/');        
    $pattern = str_replace( '\*' , '.*?', $pattern);   //> This is the important replace
    return (bool)preg_match( '/^' . $pattern . '$/i' , $source );
}

Remplacer fondamentalement * Par .*? (Compte tenu de l'environnement *nix* Correspond à la chaîne empty) © vbence

Des améliorations/suggestions?

// Ajout de return (bool) car preg_match renvoie int

28
dynamic

Il n'y a pas besoin de preg_match Ici. PHP a une fonction de comparaison générique, spécialement conçue pour de tels cas:

fnmatch()

Et fnmatch('dir/*/file', 'dir/folder1/file') fonctionnerait probablement déjà pour vous. Mais attention, le caractère générique * Ajouterait également des barres obliques supplémentaires, comme le ferait preg_match.

47
mario

Vous devez simplement utiliser .* au lieu.

$pattern = str_replace( '*' , '.*', $pattern);   //> This is the important replace

Modifier: aussi votre ^ et $ étaient dans le mauvais ordre.

<?php

function stringMatchWithWildcard($source,$pattern) {
    $pattern = preg_quote($pattern,'/');        
    $pattern = str_replace( '\*' , '.*', $pattern);   
    return preg_match( '/^' . $pattern . '$/i' , $source );
}

$mystring = 'dir/folder1/file';
$pattern = 'dir/*/file';

echo stringMatchWithWildcard($mystring,$pattern); 



$mystring = 'string bl#abla;y';
$pattern = 'string*y'; 

echo stringMatchWithWildcard($mystring,$pattern); 

Démo de travail: http://www.ideone.com/mGqp2

2
Dogbert
.+?

Provoque une correspondance non gourmande pour tous les caractères. Ce n'est PAS égal à "*" car il ne correspondra pas à la chaîne vide.

Le modèle suivant correspondra également à la chaîne vide:

.*?

donc...

stringMatchWithWildcard ("hello", "hel*lo"); // will give true
2
vbence

Vous mélangez la fin ($) et début (^). Cette:

preg_match( '/$' . $pattern . '^/i' , $source );

Devrait être:

preg_match( '/^' . $pattern . '$/i' , $source );
2
netcoder

Le seul problème que vous aurez est que l'appel à preg_quote() échappera au caractère astérisque. Étant donné que, votre str_replace() remplacera le *, Mais pas le caractère d'échappement devant lui.

Par conséquent, vous devez modifier la str_replace('*' ..) avec str_replace('\*'..)

0
Spudley
$pattern = str_replace( '\*' , '.+?', $pattern);   // at least one character
0
Tim13