这是一种情况,当你有一些东西要工作,但却对它的工作效果感到惊讶。我有点难以理解为什么下面的正则表达式,即从JSON字符串中删除注释,而不接触字符串值中的注释,在所有情况下几乎无条件地工作,无论我在注释中放了多少双引号来"欺骗"正则表达式:
$str = <<<'ndoc'
{
// comment "
"prop0": /* remove */ "hello /* preserve */ there", // remove
"prop1": /* remove " */ "hi // preserve", /* remove " */
"prop2": /* remove */ "hi // preserve"
}
ndoc;
$str = preg_replace("/'"(?<!'''''")(?:[^'''''"]++|''''{2}|''''.)*'"(*SKIP)(*FAIL)|''/''/.*(?=''R)|''/''*''C*?''*''//u", "", $str);
var_dump($str);
http://ideone.com/rLP1nq
在我看来,从第一个注释中的双引号到prop0
中的双引述的文本必须跳过,然后": /* remove */ "
必须跳过,以此类推,而不是删除需要删除的注释和删除需要保留的文本。但是regex无论如何都能正常工作。为什么?
我重新格式化了您的源代码,并向模式添加了注释。分隔符已更改为(),因此不需要对斜杠进行转义。x修改器允许格式化模式(忽略空白,可以使用#注释)。
这将使模式更易于阅读。您可以看到第一部分与"value"-字符串匹配。如果匹配,则跳过替换,否则匹配并替换//和/**/注释。
$str = <<<'ndoc'
{
// comment "
"prop0": /* remove */ "hello /* preserve */ there", // remove
"prop1": /* remove " */ "hi // preserve", /* remove " */
"prop2": /* remove */ "hi // preserve"
}
ndoc;
$pattern = "(
# a starting double quote
'"
# string contents including escape sequences
(?<!'''''")(?:[^'''''"]++|''''{2}|''''.)*
# the ending double quote
'"
# skip double quote string matches
(*SKIP)(*FAIL)
# or
|
# // comments
//.*(?=''R)
# or
|
# /* */ comments
/''*''C*?''*/
)xu";
$str = preg_replace($pattern, "", $str);
var_dump($str);