看着你的正則表達式,我會建議閱讀regex greediness.如果你選擇引號到第一個逗號之間的所有東西,你會遇到問題。第一件事返回將是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
。
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)
更新2
我想用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" }
說明
(?<!
- 開始負回顧後
:|:)
- 冒號或匹配用空格冒號並結束倒映
"
- 相匹配的報價
(?=
- 開始了積極的前瞻
[^"]*?
- 匹配任何東西,除了報價;的最小量,同時仍然具有圖案是真實
"(([^:])|([,}]))
- 匹配的報價後跟一個空格和任何東西,但結腸或它報價,隨後通過逗號或右支架匹配
)
- 端向前看
你可以read more about regex lookaheads here.我認爲這個正則表達式雖然在技術上是有效的,但它是凌亂的。我打算繼續玩,讓它更好,但我很累,所以現在我要去睡覺了。這個正則表達式允許你的數據更鬆散地輸入。這兩種工作以及它們的任意組合:
{ "test" : "testing with "data" like this" , "subject" : "trying the "special" chars" }
{"test":"testing with "data" like this","subject":"trying the "special" chars"}
在引號之間可以出現像\ n和\ t之類的轉義字符。 – vinnylinux
有沒有辦法只選擇以雙引號結束的雙引號,或者?像這樣:/:「([」] *)「[,}]/ – vinnylinux
但是,這並不能幫助我隔離雙引號內的雙引號,我想將它們隔離開來,以便用」 – vinnylinux