如何使用此preg_replace取消对JavaScript代码的注释?

Sam*_*Sam 1 javascript php obfuscation preg-replace minify

我试图// comments用我的php preg_replace()在我的javascript中取消注释并创建一个preg_replace,它应该执行以下操作:

1.当评论从新行开始时,删除整行: // COMMENTS .....

2.当评论落后于脚本时,在1 TAB之后//删除该评论部分 exampleScript(); // (1space) comments

3.在http://中与//不匹配

这个pregreplace做了上述工作,但是,它目前删除了3行代码//.(请参阅下面的错误匹配标题)它应该跳过.

$buffer = preg_replace('/(?<!http:)\/\/\s*[^\r\n]*/', '', $buffer);
Run Code Online (Sandbox Code Playgroud)

很好的比赛

//something

// something *!&~@#^hjksdhaf

功能();// comment

假匹配

(/\/\.\//)
"//"  
"://"  
Run Code Online (Sandbox Code Playgroud)

那么,我如何过滤这三个错误匹配以及如何更改以下正则表达式?

(?<!http:)\/\/\s*[^\r\n]*
Run Code Online (Sandbox Code Playgroud)

PS,我不希望使用其他人的代码minifiers /框架与他们自己的开销.就我自己而言.

Mat*_*all 6

为什么不使用预先存在的JavaScript minifier,比如YUI Compressor(这里的 PHP绑定)?


如果您真的自己编写,请查看源代码以了解它是如何完成的.
简短版本:正确的方法是使用适当的解析器/标记器方法.

  • @Sam:如果我问为什么,你介意吗?您是否将此作为学习项目使用?否则,这听起来像[NIH syndrome](http://en.wikipedia.org/wiki/Not_Invented_Here#In_computing)给我. (2认同)

Dan*_*den 6

JavaScript的语法是一种无上下文的语法(我相信它是LL(1) - 可解析的). 它无法使用正则表达式进行解析.

在可计算性理论中的形式语言理论中,有一个结果称为泵浦引理,它证明你不能用正则表达式解析任意无上下文语法.

问题的关键在于:您不能只查找字符串//,因为它可以包含在其他有效代码中,例如字符串.你不能只寻找一个//内部两个引号,因为那样你会得到误报,比如alert('no!') // can't do it文本) // can在技​​术上包含在两个'标记之间.相反,您必须检测字符串的开始和结束位置.更糟糕的是,一种类型的字符串可以嵌套在另一种类型的字符串中,字符串(甚至是半开字符串)可以嵌套在注释中!

没有简单的通用解决方案 - 像字符串,括号,圆括号等JavaScript语法元素可以任意嵌套多层次.准确检测任何语法元素开始和结束位置的唯一方法是正确解析沿途可能遇到的所有语法元素.

正确的答案是使用实际的解析器.