2012-05-09 13 views
8

ho una stringa che è come questosostituire tutte le occorrenze all'interno modello

{{ some text @ other text @ and some other text }} @ this should not be replaced {{ but this should: @ }} 

voglio che diventi

{{ some text ### other text ### and some other text }} @ this should not be replaced {{ but this should: ### }} 

Credo che l'esempio è dritto abbastanza in avanti e io non sono sicuro che può spiegare meglio ciò che voglio ottenere in parole.

Ho provato diversi approcci ma nessuno ha funzionato.

risposta

8

Ciò può essere ottenuto con un'espressione regolare richiamare ad una semplice stringa sostituire:

function replaceInsideBraces($match) { 
    return str_replace('@', '###', $match[0]); 
} 

$input = '{{ some text @ other text @ and some other text }} @ this should not be replaced {{ but this should: @ }}'; 
$output = preg_replace_callback('/{{.+?}}/', 'replaceInsideBraces', $input); 
var_dump($output); 

ho optato per una semplice espressione regolare non avidi di trovare la tua parentesi, ma si può scegliere di modificare questo per prestazioni o per soddisfare le tue esigenze.

funzioni anonime permetterebbero di parametrizzare le vostre sostituzioni:

$find = '@'; 
$replace = '###'; 
$output = preg_replace_callback(
    '/{{.+?}}/', 
    function($match) use ($find, $replace) { 
     return str_replace($find, $replace, $match[0]); 
    }, 
    $input 
); 

Documentazione: http://php.net/manual/en/function.preg-replace-callback.php

2

È possibile farlo con 2 regex. Il primo seleziona tutto il testo tra {{ e }} e il secondo sostituito @ con ###. Utilizzando 2 espressioni regolari può essere fatto in questo modo:

$str = preg_replace_callback('/first regex/', function($match) { 
    return preg_replace('/second regex/', '###', $match[1]); 
}); 

Ora si può fare la prima e la seconda regex, provare voi stessi e se non si ottiene, chiedete in questa domanda.

2

Un altro metodo sarebbe quello di utilizzare l'espressione regolare (\{\{[^}]+?)@([^}]+?\}\}). Avresti bisogno di eseguire più di un paio di volte in modo che corrisponda più @ s all'interno {{ parentesi }}:

<?php 

$string = '{{ some text @ other text @ and some other text }} @ this should not be replaced {{ but this should: @ }}'; 
$replacement = '#'; 
$pattern = '/(\{\{[^}]+?)@([^}]+?\}\})/'; 

while (preg_match($pattern, $string)) { 
    $string = preg_replace($pattern, "$1$replacement$2", $string); 
} 

echo $string; 

quali uscite:

{{testo ### altro testo ### e qualche altro testo}} @ questo dovrebbe non essere sostituito {{ma questo dovrebbe: ###}}