Я пытался избежать всех двойных кавычек внутри двойных кавычек (да, сумасшедший) целый день, и я, наконец, сдаюсь. У меня есть такие данные:
{ "test": "testing with "data" like this", "subject": "trying the "special" chars" }
Я пытаюсь preg_replace каждый "
с \"
внутри что-то вроде этого /"(.*)+, "/
что означает все внутри двойных кавычек, за которым следуют запятая и пробел.
Мне нужен способ сделать это:
{ "test": "testing with "data" like this", "subject": "trying the "special" chars" }
В этом:
{ "test": "testing with \"data\" like this", "subject": "trying the \"special\" chars" }
Использование preg_replace.
Глядя на ваше регулярное выражение, я предлагаю прочитать жадность regex. Если вы выбираете все между кавычками в первую запятую, вы столкнетесь с проблемами. Первое, что вернулось, было бы test": "testing with "data" like this
поэтому, если вы замените все "
на \"
вы бы test\": \"testing with \"data\" like this
что явно не так вы хотите. Я бы рекомендовал использовать что-то вроде этого:
/"((?:.|\n)*?)"\s*[:,}]\s*/
объяснение
"((?:.|\n)*?)"
– фиксирует любой символ между двумя котировками; минимальная сумма при сохранении шаблона \s*
– соответствует 0 или более символам пробела [:,}]
– совместить символ двоеточия, запятой или правой скобки \s*
– соответствует 0 или более символам пробела Используя это регулярное выражение и ваши данные, первое, что вернулось, это test
. Следующее, что вернулось, будет testing with "data" like this
поэтому после замены у вас будет testing with \"data\" like this
.
$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 )
Я думаю, используя preg_match_all
а затем str_replace
– лучший способ решить вашу проблему, потому что это регулярное выражение намного более стабильно. Но если вы настаиваете на использовании preg_replace
вы можете использовать этот код:
$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" }
объяснение
(?<!
– начинает отрицательный lookbehind :|: )
🙂 – соответствует двоеточие или двоеточие с пробелом и заканчивает lookbehind "
– соответствует котировке (?=
– начинает позитивный просмотр [^"]*?
– сопоставлять что-либо, кроме цитаты, минимальная сумма при все еще правильном шаблоне "(( [^:])|([,}]))
– соответствует цитате, за которой следует пробел, и всего, кроме двоеточия ИЛИ, оно соответствует цитате, за которой следует либо запятая, либо правая скобка )
– завершает просмотр Здесь вы можете узнать больше о regex lookaheads. Я думаю, что это регулярное выражение грязно, хотя технически оно работает. Я собирался продолжать играть с ним, чтобы сделать его лучше, но я устал, поэтому я сейчас ложился спать. Это регулярное выражение позволяет более гибко печатать ваши данные. Обе эти работы и любая их комбинация:
{ "test" : "testing with "data" like this" , "subject" : "trying the "special" chars" } {"test":"testing with "data" like this","subject":"trying the "special" chars"}