5
votes

For a custom script parser in PHP I would like to replace some words in a multiline string that contain double and single quotes. However, only the text that is outside the quotes can be replaced.

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

For example, I would like to replace 'apple' with 'pear', but only outside the quote sentences. So in this case only 'apple' inside 'Many apples are falling from the trees' would be targeted.

The above would give the following output:

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

How can I achieve this?

4
Can you post your PHP Parsing script so that we can suggest the modifications. - Praveen Kumar Purushothaman

4 Answers

5
votes

This function does the trick:

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;
}

How it works It splits by quoted strings but includes these quoted strings, this gives you alternating non-quoted, quoted, non-quoted, quoted etc strings in an array (some of the non-quoted strings may be blank). It then alternates between replacing the word and not replacing, so only non-quoted strings are replaced.

With your example

$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);

Output

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

I came up with this:

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);
}

The logic is: you explode string by double-quotes, so the odd elements of the returning string-array represent text outside quotes, and even ones represents text inside double-quotes.

So, you can build your output by concatenating original parts and replaced parts alternatively, ok?

Working example here: http://codepad.org/rsjvCE8s

0
votes

Just a thought: create a temporary string by removing quoted parts, replace what you need to, then add the quoted parts you removed.

0
votes

You can use preg_replace, using a regular expression to replace the words inside " "

$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);

You can add more possible searchable objects by adding another RegEx in $search, and another replace string in $replace

This RegEx uses a lookahead and lookbehind to find out if the searched string is inside of " "