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

时间:2011-03-02 03:01:39

标签: php javascript preg-replace obfuscation minify

我正在尝试使用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,我不希望使用其他人的代码缩放器/框架和他们自己的开销。我现在就是我自己的。

3 个答案:

答案 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://gskinner.com/RegExr/

http://lumadis.be/regex/test_regex.php

http://cs.union.edu/~hannayd/csc350/simulators/RegExp/reg.htm