2010-02-07 18 views
6

Sembra un problema facile da risolvere, ma non è così facile come sembra. Ho questa stringa in PHP:Espressione regolare, sostituire più barre con un solo

////%postname%/ 

Questo è un URL e non voglio mai più di una barra di fila. Non voglio mai rimuovere completamente le barre.

questo è come dovrebbe essere simile:

/%postname%/ 

Poiché la struttura potrebbe avere un aspetto diverso ho bisogno di un preg intelligenti sostituire regexp, credo. Ha bisogno di lavorare con gli URL come questo:

////%postname%//mytest/test///testing 

che dovrebbe essere convertito in questo:

/%postname%/mytest/test/testing 

risposta

16

Qui si va:

$str = preg_replace('~/+~', '/', $str); 

Oppure:

$str = preg_replace('~//+~', '/', $str); 

O anche:

$str = preg_replace('~/{2,}~', '/', $str); 

Un semplice str_replace() anche fare il trucco (se non ci sono più di due barre consecutive):

$str = str_replace('//', '/', $str); 
+0

molto più breve del previsto. Non potrei farcela. Grazie! –

+4

str_replace non farà così. hai bisogno di una funzione ricorsiva, credo. (guarda sotto) – Gal

+1

Come dice Gal, lo str_replace non funzionerà se ci sono più di due barre. Il preg_replace funzionerà ma la versione di Bart K è migliore perché non corrisponde a singole barre, solo due o più – meouw

4

Prova:

echo preg_replace('#/{2,}#', '/', '////%postname%//mytest/test///testing'); 
0
echo str_replace('//', '/', $str); 
+0

No, sostituirà ''////'' con ''//'' mentre qui è necessaria una singola barra. –

4
function drop_multiple_slashes($str) 
{ 
    if(strpos($str,'//')!==false) 
    { 
    return drop_multiple_slashes(str_replace('//','/',$str)); 
    } 
    return $str; 
} 

che sta usando str_replace

+2

Che non funzionerà a meno che non si cambi _! == 0_ in _! == falso_. Inoltre, non c'è bisogno di ricorsività: _while (strpos ($ str, '//')! == false) {$ str = str_replace ('//', '/', $ str); } return $ str; _ – GZipp

+0

@GZipp, hai ragione, l'ho modificato. Per quanto ne so, non vi è alcuna differenza nelle prestazioni tra la funzione ricorsiva e il ciclo while (ma potrei essere felicemente provato diversamente). – Gal

3

In ritardo ma tutti questi metodi rimuoveranno anche le barre http://, ma questo.

function to_single_slashes($input) { 
    return preg_replace('~(^|[^:])//+~', '\\1/', $input); 
} 

# out: http://localhost/lorem-ipsum/123/456/ 
print to_single_slashes('http:///////localhost////lorem-ipsum/123/////456/'); 
0

La mia soluzione:

while (strlen($uri) > 1 && $uri[0] === '/' && $uri[1] === '/') { 
    $uri = substr($uri, 1); 
} 
Problemi correlati