这是其中一种情况,当你得到一些工作,但惊讶于它的工作情况。我有点麻烦理解为什么下面的正则表达式,即从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);
在我看来,必须跳过第一条评论中双引号和prop0
中双引号的文本,然后必须跳过": /* remove */ "
,依此类推,不是删除需要删除的注释并删除需要保留的文本。但正则表达式无论如何都可行。为什么呢?
答案 0 :(得分:1)
我重新格式化了您的来源并为该模式添加了评论。分隔符更改为(),使得不需要转义斜杠。 x modifer允许格式化模式(忽略空格,#comments可能)。
这应该使模式更具可读性。您可以看到第一部分与“value”-String匹配。如果匹配,则跳过替换,否则匹配并替换//和/ ** / comments。
$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);