2013-03-16 11 views
67

Sono terribile con espressioni regolari. Sto cercando di sostituire questo:Sostituisci preg_replace() e modificatore con preg_replace_callback

public static function camelize($word) { 
    return preg_replace('/(^|_)([a-z])/e', 'strtoupper("\\2")', $word); 
} 

con preg_replace_callback con una funzione anonima. Non capisco cosa stia facendo \\ 2. O per quanto riguarda esattamente come preg_replace_callback funziona.

Quale sarebbe il codice corretto per raggiungere questo obiettivo?

+1

L'** e ** modificatore [deprecato] (http://php.net/manual/en/reference.pcre.pattern.modifiers.php) a partire dal PHP 5.5.0 – HamZa

+8

@HamZaDzCyberDeV so . Questo è uno dei motivi per cui voglio sostituirlo con preg_replace_callback – Casey

+2

C'è una pagina di manuale per ['preg_replace_callback'] (http://php.net/preg_replace_callback). E '\\ 2' diventerà' $ matches [2] 'in detto callback. O quale parte sei confuso riguardo specificamente? – mario

risposta

59

In un'espressione regolare, è possibile "acquisire" parti della stringa corrispondente con (brackets); in questo caso, stai catturando le parti (^|_) e ([a-z]) della partita. Questi sono numerati a partire da 1, quindi hai i riferimenti di ritorno 1 e 2. La corrispondenza 0 è l'intera stringa con corrispondenza.

Il modificatore /e prende una stringa di sostituzione, e sostituti backslash seguito da un numero (ad es \1) con l'appropriato back-di riferimento -, ma perché sei all'interno di una stringa, è necessario sfuggire alla barra rovesciata, in modo da ottenere '\\1' . Quindi (efficacemente) esegue eval per eseguire la stringa risultante come se fosse codice PHP (motivo per cui è deprecato, perché è facile da usare eval in modo non sicuro).

La funzione preg_replace_callback accetta invece una funzione di richiamata e la passa una matrice contenente i riferimenti di ritorno corrispondenti. Quindi, dove avresti scritto '\\1', hai invece accesso all'elemento 1 di quel parametro - ad es. se si dispone di una funzione anonima del modulo function($matches) { ... }, il primo riferimento all'indietro è $matches[1] all'interno di tale funzione.

Quindi un argomento /e di

'do_stuff(\\1) . "and" . do_stuff(\\2)' 

potrebbe diventare un callback di

function($m) { return do_stuff($m[1]) . "and" . do_stuff($m[2]); } 

o nel vostro caso

'strtoupper("\\2")' 

potrebbe diventare

function($m) { return strtoupper($m[2]); } 

Nota che $m e $matches non sono nomi magici, sono solo il nome del parametro che ho dato quando dichiaro le mie funzioni di callback. Inoltre, non è necessario passare una funzione anonima, potrebbe essere un nome di funzione come una stringa o qualcosa del formato array($object, $method), as with any callback in PHP, ad es.

function stuffy_callback($things) { 
    return do_stuff($things[1]) . "and" . do_stuff($things[2]); 
} 
$foo = preg_replace_callback('/([a-z]+) and ([a-z]+)/', 'stuffy_callback', 'fish and chips'); 

Come con qualsiasi funzione, non è possibile accedere alle variabili al di fuori di richiamata (dal campo di applicazione circostante) per impostazione predefinita. Quando si utilizza una funzione anonima, è possibile utilizzare la parola chiave use per importare le variabili a cui è necessario accedere, as discussed in the PHP manual. per esempio.se il vecchio argomento era

'do_stuff(\\1, $foo)' 

poi il nuovo callback potrebbe sembrare

function($m) use ($foo) { return do_stuff($m[1], $foo); } 

trucchi

  • L'utilizzo di preg_replace_callback è invece di del /e modificatore sul regex, in modo da è necessario rimuovere quel flag dal tuo argomento "pattern". Quindi uno schema come /blah(.*)blah/mei diventerebbe /blah(.*)blah/mi.
  • Il modificatore /e utilizzava una variante di addslashes() internamente sugli argomenti, quindi alcune sostituzioni utilizzavano stripslashes() per rimuoverlo; nella maggior parte dei casi, probabilmente si desidera rimuovere la chiamata a stripslashes dal nuovo callback.