2012-06-07 33 views
5

Para un analizador de scripts personalizado en PHP Me gustaría reemplazar algunas palabras en una cadena de varias líneas que contienen comillas dobles e individuales. Sin embargo, solo el texto que es fuera de las comillas se pueden reemplazar.Cómo reemplazar palabras fuera de comillas dobles o simples

Many apples are falling from the trees.  
"There's another apple over there!"  
'Seedling apples are an example of "extreme heterozygotes".' 

Por ejemplo, me gustaría reemplazar 'apple' por 'pear', pero solo fuera de las frases de comillas. Entonces, en este caso, solo la 'manzana' dentro 'Muchas manzanas caen de los árboles' sería atacada.

Lo anterior daría el siguiente resultado:

Many pears are falling from the trees.  
"There's another apple over there!"  
'Seedling apples are an example of "extreme heterozygotes".' 

¿Cómo puedo lograr esto?

+0

Se puede publicar su script PHP de análisis para que podamos sugerir las modificaciones. –

Respuesta

6

Esta función hace el truco:

function str_replace_outside_quotes($replace,$with,$string){ 
    $result = ""; 
    $outside = preg_split('/("[^"]*"|\'[^\']*\')/',$string,-1,PREG_SPLIT_DELIM_CAPTURE); 
    while ($outside) 
     $result .= str_replace($replace,$with,array_shift($outside)).array_shift($outside); 
    return $result; 
} 

Cómo funciona Se divide por cadenas entre comillas, sino que incluye estas cadenas entre comillas, esto le da la alternancia no citado, citado, no citado, citado cuerdas, etc. en una matriz (algunas de las cadenas no citadas pueden estar en blanco). Luego alterna entre reemplazar la palabra y no reemplazar, por lo que solo se reemplazan las cadenas no citadas.

Con tu ejemplo

$text = "Many apples are falling from the trees.  
     \"There's another apple over there!\"  
     'Seedling apples are an example of \"extreme heterozygotes\".'"; 
$replace = "apples"; 
$with = "pears"; 
echo str_replace_outside_quotes($replace,$with,$text); 

salida

Many pears are falling from the trees.  
"There's another apple over there!"  
'Seedling apples are an example of "extreme heterozygotes".' 
+0

¡Trabajando bien, muchas gracias! – Nick

+0

No pude obtener la expresión regular utilizada en mi [primera respuesta] (http://stackoverflow.com/revisions/10929115/1) para que funcione de manera confiable, así que creé esta función en su lugar, que siempre funciona. – Timm

+0

Probé tu script y encontré un error. Si tiene los caracteres \ "o \" escapados en su cadena, se cerrará pronto y generará resultados impredecibles. Esta expresión regular lo corrige/('(?: [^ \\\\'] + | \\\\ (\\ \\\\\\) *.) * '| \ "(?: [^ \\\\\"] + | \\\\ (\\\\\\\\) *.) * \ " /. No es bonito, pero funciona. Debe haber una solución más elegante, pero no puedo perder más tiempo en esto ahora mismo. –

0

Solo un pensamiento: crea una cadena temporal quitando las partes citadas, reemplaza lo que necesitas y luego agrega las partes citadas que quitaste.

+0

¿Cómo se vuelven a agregar las partes citadas a la cadena original, en sus posiciones originales? – Nick

1

me ocurrió esto:

function replaceOutsideDoubleQuotes($search, $replace, $string) { 
    $out = ''; 
    $a = explode('"', $string); 
    for ($i = 0; $i < count($a); $i++) { 
     if ($i % 2) $out .= $a[$i] . '"'; 
     else $out .= str_replace($search, $replace, $a[$i]) . '"'; 
    } 
    return substr($out, 0, -1); 
} 

La lógica es: explotas cadena mediante comillas dobles, por lo que los impares elementos de la cadena de matriz regresar representan texto fuera de las cotizaciones, y incluso unos representa texto dentro de comillas dobles.

Por lo tanto, puede construir su salida mediante la concatenación de piezas originales y piezas sustituidas de forma alternativa, ¿está bien?

Ejemplo de trabajo aquí: http://codepad.org/rsjvCE8s

+0

Gracias, pero funciona solo para las comillas dobles ... Necesitaría algo que solo reemplaza fuera de comillas dobles Y simples :) – Nick

0

Usted puede utilizar preg_replace, utilizando una expresión regular para sustituir las palabras dentro ""

$search = array('/(?!".*)apple(?=.*")/i'); 
$replace = array('pear'); 
$string = '"There\'s another apple over there!" Seedling apples are an example of "extreme heterozygotes".'; 

$string = preg_replace($search, $replace, $string); 

se puede añadir más objetos de búsqueda posibles mediante la adición de otra RegEx en $ search, y otra cadena de reemplazo en $ replace

Este RegEx usa un lookahead y lookbehind para descubrir si la cadena buscada está dentro de ""

+0

Lo siento, me acabo de dar cuenta de que leí la pregunta incorrectamente - se hizo lo contrario. Lo cambiaré ... – Katai

+0

Parece hacer lo contrario de lo que pregunta, reemplazando el texto ** dentro ** de las comillas, y no afuera. –

Cuestiones relacionadas