Regex to avoid double quotes inside double quotes with preg_replace

I tried to avoid all double quotes inside double quotes (yes, crazy) all day, and I finally give up. I have the following data:

{ "test": "testing with "data" like this", "subject": "trying the "special" chars" } 

I try to preg_replace every " c \" inside something like this /"(.*)+, "/ , which means everything inside double quotes, followed by a comma and a space.

I need a way to do this:

 { "test": "testing with "data" like this", "subject": "trying the "special" chars" } 

In it:

 { "test": "testing with \"data\" like this", "subject": "trying the \"special\" chars" } 

Using preg_replace.

+4
source share
1 answer

Looking at your regular expression, I suggest reading the greed of regular expression. If you select everything between quotation marks in the first comma, you will run into problems. The first thing that was returned will be test": "testing with "data" like this , so if you replace everything with " \" , you will have test\": \"testing with \"data\" like this , which clearly not what you want. I would recommend using something like this:

 /"((?:.|\n)*?)"\s*[:,}]\s*/ 

Explanation

  • "((?:.|\n)*?)" - fixes any character between two quotes; the minimum amount when saving the template will be true.
  • \s* - matches 0 or more space characters
  • [:,}] - match the colon, comma, or right bracket character
  • \s* - matches 0 or more space characters

Using this regular expression and your data, the first thing returned is test . The next thing that came back will be testing with "data" like this , so after replacing you will have testing with \"data\" like this .


UPDATE
 $test = '{ "test": "testing with "data" like this", "subject": "trying the "special" chars" }'; $pattern = '/"((?:.|\n)*?)"\s*[:,}]\s*/'; preg_match_all($pattern, $test, $matches); foreach($matches[1] as $match){ $answers[] = str_replace('"','\\"',$match); } print_r($answers); // Outputs // Array ( [0] => test [1] => testing with \"data\" like this [2] => subject [3] => trying the \"special\" chars ) 


UPDATE 2

I think using preg_match_all and then str_replace is the best way to solve your problem, because this regex is much more stable. But if you insist on using preg_replace , you can use this code:

 $string = '{ "test": "testing with "data" like this", "subject": "trying the "special" chars" }'; $pattern = '/(?<!:|: )"(?=[^"]*?"(( [^:])|([,}])))/'; $string = preg_replace($pattern, '\\"', $string); print_r($string); //Outputs //{ "test": "testing with \"data\" like this", "subject": "trying the \"special\" chars" } 

Explanation

  • (?<! - launches a negative lookbehind
  • :|: ) - matches a colon or colon with a space and ends lookbehind
  • " - matches quote
  • (?= - starts a positive view
  • [^"]*? - match everything except the quote; the minimum amount when saving the template will be true.
  • "(( [^:])|([,}])) - matches a quote followed by a space, and everything except the colon OR, it matches a quote followed by either a comma or a right bracket
  • ) - ends the view

Read more here. I think this regex is dirty, although technically it works. I was going to continue playing with him to make him better, but I was tired, so I went to bed now. This regular expression allows you to print your data more flexibly. Both of these works and any combination of them:

 { "test" : "testing with "data" like this" , "subject" : "trying the "special" chars" } {"test":"testing with "data" like this","subject":"trying the "special" chars"} 
+9
source

Source: https://habr.com/ru/post/1432595/


All Articles