2010-04-14 14 views
14

mi hanno nomi come questo:preg_replace rendere maiuscola una lettera, dopo un preventivo

$str = 'JAMES "JIMMY" SMITH' 

corro strtolower, poi ucwords, che restituisce questo:

$proper_str = 'James "jimmy" Smith' 

vorrei sfruttare il secondo lettera di parole in cui la prima lettera è una doppia citazione. Ecco le espressioni regolari. Sembra che strtoupper non funzioni: la regexp restituisce semplicemente l'espressione originale invariata.

$proper_str = preg_replace('/"([a-z])/',strtoupper('$1'),$proper_str); 

Eventuali indizi? Grazie!!

+0

Quale output ti aspetti? – codaddict

risposta

20

Utilizzare il e modifier di avere la sostituzione valutare:

preg_replace('/"[a-z]/e', 'strtoupper("$0")', $proper_str) 

Dove $0 contiene partita per l'intero modello, così " e la lettera minuscola. Ma non importa dal momento che il " non cambia quando si invia attraverso strtoupper.

+0

Ha funzionato come un incantesimo Grazie, – Summer

+0

Penso di aver reso tutto più difficile di quanto non debba essere come' strtoupper ('"') === '"' '.; ;-) – Gumbo

+20

Apparentemente l'opzione 'e' è una grave vulnerabilità di sicurezza e raccomandano invece di usare' preg_replace_callback() '. FYI. –

31

Probabilmente il modo migliore per farlo è usare :

$str = 'JAMES "JIMMY" SMITH'; 
echo preg_replace_callback('!\b[a-z]!', 'upper', $str); 

function upper($matches) { 
    return strtoupper($matches[0]); 
} 

È possibile utilizzare il (eval) bandiera e su preg_replace() ma io in genere consigliare contro di essa. Soprattutto quando si tratta di input esterni, è potenzialmente estremamente pericoloso.

+0

Ho ricevuto un errore che "upper" non è un callback valido.Quando ho sostituito "upper" con "strtoupper", ho ottenuto "ARRAY" invece di maiuscola "J" – Summer

+0

@Summer, quindi non hai definito la funzione 'upper()' come per il mio snippet di codice. – cletus

+0

Com'è giusto. Grazie. – Summer

0

Qualcosa di simile potrebbe fare il trucco:

preg_replace("/(\w+)/e", "ucwords(strtolower('$1'))", $proper_str); 
0

faccio questo senza espressione regolare, come parte della mia funzione personalizzata ucwords(). Supponendo che non più di due citazioni appaiono nella stringa:

$parts = explode('"', $string, 3); 
if(isset($parts[2])) $string = $parts[0].'"'.ucfirst($parts[1]).'"'.ucfirst($parts[2]);    
else if(isset($parts[1])) $string = $parts[0].'"'.ucfirst($parts[1]); 
16

Usa preg_replace_callback - Ma non avete bisogno di aggiungere una funzione extra di nome, piuttosto utilizzare una funzione anonima.

$str = 'JAMES "JIMMY" SMITH'; 
echo preg_replace_callback('/\b[a-z]/', function ($matches) { 
    return strtoupper($matches[0]); 
}, $str); 

L'uso della /e è essere deprecato in PHP 5.5 e non funziona in PHP 7

0

Si dovrebbe fare questo:

$proper_str = 
    preg_replace_callback(
     '/"([a-z])/', 
     function($m){return strtoupper($m[1]);}, 
     $proper_str 
); 

È should'nt usare "eval() " per motivi di sicurezza.

In ogni caso, il modificatore patern "e" è deprecato. Vedi: PHP Documentation.

0
echo ucwords(mb_strtolower('JAMES "JIMMY" SMITH', 'UTF-8'), ' "'); // James "Jimmy" Smith 

ucwords() ha un secondo parametro delimitatore, i delimitatori opzionali contiene i caratteri separatori di parola. Usa lo spazio '' e " come delimitatore e "Jimmy" verrà riconosciuto correttamente.

Problemi correlati