-2

I have a string where there are sections with double quotes.Im trying to replace all the double quotes with single quotes except ones that have escaping ie: \".

I'm trying to build a regex that matches all " except ones that comes like \"

So when I use preg_replace I will get as follows.

"love" -> 'love'

"John said \"HI\"" - > 'John said \"HI\"' 

I have tried the following which does exactly the opposite.

[<^\\]"
yivi
  • 42,438
  • 18
  • 116
  • 138
  • simple note: you won't be able to detect specifically escaped `"` in `"John said \"HI\""`, the "\" is not in the string anymore. If not escaped, on the contratry, it would be a syntax error. Or maybe do you have `"John said \\\"HI\\\""`? – Kaddath Oct 26 '17 at 13:48
  • @Jan This question is an evident duplicate, there is a good solution already, why not close? Your answer is incorrect anyway. – Wiktor Stribiżew Oct 26 '17 at 13:55
  • 1
    @WiktorStribiżew: Why should it be incorrect? Btw, [this question](https://stackoverflow.com/questions/46952713/regex-pattern-matching-takes-a-long-time-for-strings-with-length-more-than-30-ch) with your answer having four upvotes so far has been asked a zillion times on SO (problem is the backtracking), why not close this as well? – Jan Oct 26 '17 at 13:58
  • @Jan Backtracking related questions are never evident. If you find a question with the identical pattern, I will close that question. Your solution here does not account for escaped backslashes. – Wiktor Stribiżew Oct 26 '17 at 14:07
  • @WiktorStribiżew: A search for ["regex takes long time"](https://stackoverflow.com/search?q=regex+takes+long+time) reveals [**this question**](https://stackoverflow.com/questions/36864281/regex-takes-a-long-time-to-complete) (btw. answered by you), [**this question**](https://stackoverflow.com/questions/7464895/regex-taking-a-long-time) and [**this question**](https://stackoverflow.com/questions/41864096/why-does-this-regular-expression-take-a-long-time-to-run). – Jan Oct 26 '17 at 14:47
  • @WiktorStribiżew: The last one was marked as an exact duplicate of [**this one**](https://stackoverflow.com/questions/25982466/why-does-this-take-so-long-to-match-is-it-a-bug) - all of them have a good explanation on catastrophic backtracking. – Jan Oct 26 '17 at 14:48
  • @WiktorStribiżew: Concerning your other point: my answer does not account for escaped backslashes but this was not a requirement. See, I know that you are brilliant in regular expressions and programming in general but sometimes I find the decisions on closing a bit incomprehensible - after all, at least two thirds of the underlying mechanisms of the questions have been asked before on SO. – Jan Oct 26 '17 at 14:52
  • @WiktorStribiżew even though my use case here is a escaped double quote.my question is general.The accepted answer can be applied to any similar account. – Shalitha Vikum Oct 26 '17 at 15:19
  • @ShalithaVikum You should be aware that a plain lookbehind approach [does not let you match valid unescaped quotes if they are preceded with a literal backslash](https://regex101.com/r/2WNJDN/1) (represented in the string literal with two consecutive backslashes). So, the solution you accepted will not work for a general case. – Wiktor Stribiżew Oct 26 '17 at 19:56

1 Answers1

6

You could use a neg. lookbehind:

(?<!\\)"

See a demo on regex101.com.


In PHP:
<?php

$strings = ['"love"', '"John said \"HI\""'];

$regex = '~(?<!\\\\)"~';

foreach ($strings as $string) {
    echo preg_replace($regex, "'", $string) . "\n";
}

?>

This yields

'love'
'John said \"HI\"'

Be aware though that the backslash needs to be escaped as well in PHP, so that you'll need four backslashes in total here.

Jan
  • 42,290
  • 8
  • 54
  • 79