2010-02-07 12 views
6

Wydaje się, że jest to łatwy problem do rozwiązania, ale nie jest to takie proste, jak się wydaje. Mam ten ciąg w PHP:Wyrażenie regularne, zamień kilka ukośników tylko na jeden

////%postname%/ 

Jest to URL i nigdy nie chce więcej niż jeden ukośnik w rzędzie. Nigdy nie chcę całkowicie usunąć ukośników.

To jak to powinno wyglądać:

/%postname%/ 

Ponieważ struktura mogłaby wyglądać inaczej muszę sprytny preg zastąpić wyrażeniem regularnym, tak myślę. To trzeba pracować z adresami URL tak:

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

które powinny zostać przekształcone do tego:

/%postname%/mytest/test/testing 

Odpowiedz

16

Proszę bardzo:

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

Lub:

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

Lub nawet:

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

Prosty str_replace() również rade (jeżeli nie ma więcej niż dwa kolejne ukośniki):

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

znacznie krótszy niż oczekiwano. Nie mogłem zmusić go do niepowodzenia. Dzięki! –

+4

str_replace tego nie zrobi. potrzebujesz funkcji rekurencyjnej, w którą wierzę. (spójrz poniżej) – Gal

+1

Jak mówi Gal, str_replace nie zadziała, jeśli są więcej niż dwa ukośniki. Preg_replace będzie działał, ale wersja Bart K jest lepsza, ponieważ nie pasuje do pojedynczych ukośników, tylko dwa lub więcej – meouw

4

Spróbuj:

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

Nie, to zastąpi '' //// '' z ''//'', podczas gdy tutaj potrzebny jest pojedynczy ukośnik. –

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

że używa str_replace

+2

To nie zadziała, chyba że zmienisz _! == 0_ na _! == false_. Dodatkowo, nie ma potrzeby rekursji: _while (strpos ($ str, '//')! == false) {$ str = str_replace ('//', '/', $ str); } return $ str; _ – GZipp

+0

@GZipp, masz rację, ja to zredagowałem. O ile mi wiadomo, nie ma różnicy w wydajności między funkcją rekursywną a pętlą while (ale z drugiej strony można by udowodnić, że jest inaczej). – Gal

3

Późno, ale wszystkie te metody usuwają też ukośniki o wartości http://, ale to.

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

Moje rozwiązanie:

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