看着你的正则表达式,我会建议阅读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