あなたの正規表現を見ると、正規表現の貪欲さについて読むことをお勧めします。引用符から最初のコンマまでのすべてを選択すると、問題が発生します。最初に返されるのは、すべてをtest": "testing with "data" like this
置き換えた場合、明らかにあなたが望んでいるものではないということです。次のようなものを使用することをお勧めします。"
\"
test\": \"testing with \"data\" like this
/"((?:.|\n)*?)"\s*[:,}]\s*/
説明
"((?:.|\n)*?)"
- 2 つの引用符の間の任意の文字をキャプチャします。パターンが true である場合の最小量
\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 )
更新 2
その正規表現ははるかに安定しているため、preg_match_all
and thenを使用する方が問題を解決するためのより良い方法だと思います。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" }
説明
(?<!
- 否定後読みを開始します
:|: )
- コロンまたはコロンとスペースを照合し、後読みを終了します
"
- 引用に一致
(?=
- 前向きな先読みを開始します
[^"]*?
- 引用符以外のすべてに一致します。パターンが true である場合の最小量
"(( [^:])|([,}]))
- 引用符の後にスペースとコロン以外が続くものに一致、または引用符の後にコンマまたは右角かっこが続くものに一致
)
- 先読みを終了します
正規表現の先読みについて詳しくは、こちらをご覧ください。技術的には機能しますが、この正規表現は面倒だと思います。もっと良くするためにずっと遊んでいたつもりだったのですが、疲れたので今は寝ます。この正規表現を使用すると、データをより緩やかに型指定できます。これらの両方、およびそれらの任意の組み合わせが機能します。
{ "test" : "testing with "data" like this" , "subject" : "trying the "special" chars" }
{"test":"testing with "data" like this","subject":"trying the "special" chars"}