从JSON数据中删除注释

3
我需要从JSON数据中删除所有/*...*/格式的注释。如何使用正则表达式完成呢?以使像这样的字符串值保留:
{
    "propName": "Hello \" /* hi */ there."
}

保持不变?


@MihaiIorga 对于 "prop0": /* comment */ "Hello" 这种注释不起作用。 - Desmond Hume
@AmalMurali 同样的事情。 - Desmond Hume
@DesmondHume 为什么你不试一下呢?$code = preg_replace('#/\*(?:.(?!/)|[^\*](?=/)|(?<!\*)/)*\*/#s', '', $code); - Mihai Iorga
@MihaiIorga 你提出的代码会在字符串值包含 /*...*/ 的情况下修改该字符串的值。 - Desmond Hume
@MihaiIorga 是的,那就是我需要的,实际上在问题中已经提到了。 - Desmond Hume
显示剩余4条评论
1个回答

5

在使用回溯控制动词SKIPFAIL(或一个捕获)之前,您必须先避免所有位于双引号内的内容。

$string = <<<'LOD'
{
    "propName": "Hello \" /* don't remove **/ there." /*this must be removed*/
}
LOD;

$result = preg_replace('~"(?:[^\\\"]+|\\\.)*+"(*SKIP)(*FAIL)|/\*(?:[^*]+|\*+(?!/))*+\*/~s', '',$string);

// The same with a capture:

$result = preg_replace('~("(?:[^\\\"]+|\\\.)*+")|/\*(?:[^*]+|\*+(?!/))*+\*/~s', '$1',$string);

模式细节:

"(?:[^\\\"]+|\\\.)*+"

这部分描述引号内可能包含的内容:
"              # literal quote
(?:            # open a non-capturing group
    [^\\\"]+   # all characters that are not \ or "
  |            # OR
    \\\.)*+    # escaped char (that can be a quote)
"

您可以使用(*SKIP)(*FAIL)(*SKIP)(?!)使此子模式失败。如果模式在此之后失败,SKIP将禁止回溯。 FAIL强制模式失败。因此,引用部分将被跳过(并且不能在结果中,因为您在子模式之后使其失败)。

或者您可以使用捕获组,并在替换模式中添加该引用。

/\*(?:[^*]+|\*+(?!/))*+\*/

这部分描述了注释中的内容。
/\*           # open the comment
(?:           
    [^*]+     # all characters except *
  |           # OR
    \*+(?!/)  # * not followed by / (note that you can't use 
              # a possessive quantifier here)
)*+           # repeat the group zero or more times
\*/           # close the comment
在引号内部,只有在反斜杠位于换行符之前时才使用“s”修饰符。 在引号内部,只有当反斜杠在换行符之前时才会使用“s”修饰符。

两种方法都不起作用。似乎受到 \" 的影响,应完全忽略它。 - Desmond Hume
@DesmondHume:我已经测试了这段代码,它运行良好。我建议你按照原样测试代码。我认为问题出在其他地方。 - Casimir et Hippolyte
@DesmondHume:好的,这是因为我忘记使用三个反斜杠。我会纠正它。 - Casimir et Hippolyte
非常感谢。但是SKIP和FAIL对我来说仍然是个谜。 - Desmond Hume
哦,你认为 \\\{2} 可以被删除,因为它的情况已经被 \\\. 覆盖了吗? - Desmond Hume
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接