Replace all occurences of char inside quotes on PHP

前端 未结 4 1089
我在风中等你
我在风中等你 2021-01-28 02:36

How could I convert something like this:

\"hi (text here) and (other text)\" come (again)

To this:

\"hi \\(text here\\) and \\(         


        
相关标签:
4条回答
  • 2021-01-28 02:47

    Given the string

    $str = '"hi (text here) and (other text)" come (again) "maybe (to)morrow?" (yes)';
    

    Iterative method

     for ($i=$q=0,$res='' ; $i<strlen($str) ; $i++) {
       if ($str[$i] == '"') $q ^= 1;
       elseif ($q && ($str[$i]=='(' || $str[$i]==')')) $res .= '\\';
       $res .= $str[$i];
     }
    
     echo "$res\n";
    

    But if you're a fan of recursion

     function rec($i, $n, $q) {
       global $str;
       if ($i >= $n) return '';
       $c = $str[$i];
       if ($c == '"') $q ^= 1;
       elseif ($q && ($c == '(' || $c == ')')) $c = '\\' . $c;
       return $c . rec($i+1, $n, $q);
     }
    
     echo rec(0, strlen($str), 0) . "\n";
    

    Result:

    "hi \(text here\) and \(other text\)" come (again) "maybe \(to\)morrow?" (yes)
    
    0 讨论(0)
  • 2021-01-28 02:48

    This should do it for both single and double quotes:

    $str = '"hi \(text here)" and (other text) come \'(again)\'';
    
    $str = preg_replace_callback('`("|\').*?\1`', function ($matches) {
        return preg_replace('`(?<!\\\)[()]`', '\\\$0', $matches[0]);
    }, $str);
    
    echo $str;
    

    output

    "hi \(text here\)" and (other text) come '\(again\)'
    

    It is for PHP >= 5.3. If you have a lower version (>=5) you have to replace the anonymous function in the callback with a separate function.

    0 讨论(0)
  • 2021-01-28 02:51

    You can use preg_replace_callback for this;

    // outputs: hi \(text here\) and \(other text\) come (again)
    print preg_replace_callback('~"(.*?)"~', function($m) {
        return '"'. preg_replace('~([\(\)])~', '\\\$1', $m[1]) .'"';
    }, '"hi (text here) and (other text)" come (again)');
    

    What about already escaped strings;

    // outputs: hi \(text here\) and \(other text\) come (again)
    print preg_replace_callback('~"(.*?)"~', function($m) {
        return '"'. preg_replace('~(?:\\\?)([\(\)])~', '\\\$1', $m[1]) .'"';
    }, '"hi \(text here\) and (other text)" come (again)');
    
    0 讨论(0)
  • 2021-01-28 02:51

    Here's how you can do it with the preg_replace_callback() function.

    $str = '"hi (text here) and (other text)" come (again)';
    $escaped = preg_replace_callback('~(["\']).*?\1~','normalizeParens',$str);
    // my original suggestion was '~(?<=").*?(?=")~' and I had to change it
    // due to your 2nd edit in your question. But there's still a chance that
    // both single and double quotes might exist in your string.
    
    function normalizeParens($m) {
        return preg_replace('~(?<!\\\)[()]~','\\\$0',$m[0]);
        // replace parens without preceding backshashes
    }
    var_dump($str);
    var_dump($escaped);
    
    0 讨论(0)
提交回复
热议问题