2011-05-28 22 views
23

Quiero dar la posibilidad de unir la cadena con el comodín *.cadena de php que coincide con comodín *?

Ejemplo

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

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

Ejemplo 2:

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

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

pensé algo como:

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

reemplazando Básicamente *-.*? (teniendo en *nix ambiente * partidos empty cadena) © vbence

¿Alguna mejora/sugerencia?

// Agregado return (bool) porque los rendimientos preg_match int

Respuesta

35

No hay necesidad de preg_match aquí.PHP tiene una función de comparación de comodín, hecho específicamente para estos casos:

fnmatch()

Y fnmatch('dir/*/file', 'dir/folder1/file') sería probablemente ya trabajar para usted. Pero ten en cuenta que el comodín * también agregará barras adicionales, como lo haría preg_match.

+0

hola mario. fnmatches tiene alguna otra característica como '[]'. Solo necesito '*' como "char especial" – dynamic

+2

fnmatch no es compatible con sistemas que no sean POSIX. (Veo que php5.3 + también es compatible con Windows ahora). Entonces esta no es siempre la mejor manera – Pinoniq

0

El único problema que tendrás es que la llamada a preg_quote() escapará el carácter asterisco. Dado que, su str_replace() reemplazará el *, pero no el carácter de escape en frente de él.

lo tanto, debe cambiar el str_replace('*' ..) con str_replace('\*'..)

+0

me perdí de la documentación mi mal. corregido – dynamic

1

Usted sólo debe utilizar .* lugar.

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

Editar: También su ^ y $ estaban en el orden equivocado.

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

demostración de trabajo: http://www.ideone.com/mGqp2

+0

No sé si deseo dar la posibilidad de unir este '' dir // file'' con ''dir/*/file'' – dynamic

+0

'. * 'es codicioso, se comerá todo el resto de su cadena, no solo la cantidad mínima de caracteres para continuar con los patrones. Entonces, si tiene algo después de '. *', El resultado siempre será falso. – vbence

+0

Pensé que era exactamente lo que quería hacer con '. +?' De su descripción. – Dogbert

2
.+? 

Causas juego no expansivo para todos los caracteres. Esto NO es igual a "*" porque no coincidirá con la cadena vacía.

El siguiente patrón coincidirá con la cadena vacía también:

.*? 

así que ...

stringMatchWithWildcard ("hello", "hel*lo"); // will give true 
+0

¿crees que debería permitir una cadena vacía? Considere dir también: ''dir // file'' matching'' dir/*/file''? – dynamic

+0

Si desea que funcione de manera análoga a cómo funcionan las shells del sistema operativo, debe permitir la cadena vacía. Simplemente intente con 'echo> hello' seguido de' dir hello * 'en windows o' ls hello * 'en * nix. En este contexto * coincide con la cadena vacía. – vbence

+0

Sería educado dar un comentario con su -1. – vbence

2

va a mezclar hasta que termina ($) y comenzando (^). Este:

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

debe ser:

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