我正在尝试使用php preg_replace()在我的javascript中解除我的// comments
并创建一个preg_replace,它应该执行以下操作:
1.当评论从新行开始时,删除整行:
// COMMENTS .....
2.当评论在脚本后面的一半时,在TAB之后//删除该评论部分
exampleScript(); // (1space) comments
3.与http://
中的//不匹配这个pregreplace执行上述工作,但是,它目前删除了包含//
的3行代码。(请参阅下面的错误匹配标题),它应该跳过。
$buffer = preg_replace('/(?<!http:)\/\/\s*[^\r\n]*/', '', $buffer);
良好匹配
//something
// something *!&~@#^hjksdhaf
功能(); // comment
错误匹配
(/\/\.\//)
"//"
"://"
那么,如何过滤这三个错误匹配以及如何更改以下正则表达式?
(?<!http:)\/\/\s*[^\r\n]*
PS,我不希望使用其他人的代码缩放器/框架和他们自己的开销。我现在就是我自己的。
答案 0 :(得分:6)
为什么不使用预先存在的JavaScript缩小器,例如YUI Compressor(PHP绑定here)?
如果您真的自己编写,请查看source code以了解它是如何完成的。
简短版本:正确的方法是使用适当的解析器/标记器方法。
答案 1 :(得分:6)
JavaScript的语法是一种无上下文的语法(我相信它是LL(1) - 可解析的)。 无法使用正则表达式进行解析。
在可计算性理论中的形式语言理论中,有一个结果称为泵浦引理,它证明你不能用正则表达式解析任意无上下文语法。
问题的要点是:你不能只查找字符串//
,因为它可以包含在其他有效代码中,例如字符串。你不能只在两个引号内找到//
,因为那样你会得到alert('no!') // can't do it
这样的误报,其中文本) // can
在技术上包含在两个'
之间分数。相反,您必须检测字符串的开始和结束位置。更糟糕的是,一种类型的字符串可以嵌套在另一种类型的字符串中,字符串(甚至半开字符串)可以嵌套在注释中!
没有简单的通用解决方案 - 像字符串,括号,圆括号等JavaScript语法元素可以任意嵌套多层次。准确检测任何语法元素开始和结束位置的唯一方法是正确解析 all 您可能遇到的语法元素。
正确答案是使用实际的解析器。
答案 2 :(得分:1)
$buffer = preg_replace('/(?<!\S)\/\/\s*[^\r\n]*/', '', $buffer);
适用于问题中提到的所有实例:保留正匹配,删除错误匹配。
网上有三个很棒的网站,有助于找到正确的正则表达式:
http://lumadis.be/regex/test_regex.php
http://cs.union.edu/~hannayd/csc350/simulators/RegExp/reg.htm