一个简单的正则表达式搜索和替换在PHP中缩小/压缩javascript?

时间:2011-05-14 03:20:38

标签: php javascript compression minify

你可以在php中发布正则表达式搜索和替换来缩小/压缩javascript吗?

例如,这是一个简单的CSS

  header('Content-type: text/css');
  ob_start("compress");
  function compress($buffer) {
    /* remove comments */
    $buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);
    /* remove tabs, spaces, newlines, etc. */
    $buffer = str_replace(array("\r\n", "\r", "\n", "\t", '  ', '    ', '    '), '', $buffer);
    return $buffer;
  }

  /* put CSS here */

  ob_end_flush();

这是html的一个:

<?php
/* Minify All Output - based on the search and replace regexes. */
function sanitize_output($buffer)
{
    $search = array(
        '/\>[^\S ]+/s', //strip whitespaces after tags, except space
        '/[^\S ]+\</s', //strip whitespaces before tags, except space
        '/(\s)+/s'  // shorten multiple whitespace sequences
        );
    $replace = array(
        '>',
        '<',
        '\\1'
        );
  $buffer = preg_replace($search, $replace, $buffer);
    return $buffer;
}
ob_start("sanitize_output");
?>
<html>...</html>

但是对于javascript来说呢?

4 个答案:

答案 0 :(得分:4)

用于缩小/压缩javascript的简单正则表达式不太可能存在于任何地方。这可能有几个很好的理由,但这里有几个原因:

换行符和分号 好的javascript minifiers删除所有额外的换行符,但因为javascript引擎在每个语句的末尾都不会使用分号,所以minifier可以很容易地破坏这段代码,除非它足够复杂以观察和处理不同的编码样式。

动态语言构造 许多优秀的javascript minifiers也会更改变量和函数的名称以缩小代码。例如,在您的文件中调用12次的名为“strip_white_space”的函数可能会重命名为简单的“a”,在您的缩小代码中可节省192个字符。除非你的文件有很多的评论和/或空格,否则这些优化就是大部分文件大小节省的来源。

不幸的是,这比尝试处理的简单正则表达式复杂得多。假设你做了一件简单的事情:

var length = 12, height = 15;
    // other code that uses these length and height values

var arr = [1, 2, 3, 4];
for (i = (arr.length - 1); i >= 0; --i) {
    //loop code
}

这是所有有效的代码。但是,minifier如何知道要替换什么?第一个“长度”在它之前有“var”(但它没有),但是“height”在它之前只有一个逗号。如果缩小器足够智能以正确地替换第一个“长度”,那么当用作阵列的属性时,必须知道不要更改“长度”这个词有多聪明?如果你定义了一个javascript对象,你明确地定义了一个“length”属性并用相同的点符号引用它,那将会变得更加复杂。

非正则表达式选项使用比简单正则表达式更复杂的解决方案来解决此问题的几个项目,但是其中许多都没有尝试更改变量名称,所以我仍然坚持使用Dean Edwards' packerDouglas Crockford's JSMin或类似YUI Compressor的内容。

PHP implementation of Douglas Crockford's JSMin

https://github.com/mrclay/minify

答案 1 :(得分:1)

我正在写我自己的minifier因为我里面有一些PHP 。 还有一个没有解决的问题。 Preg_replace不能将引号作为边界处理,或者更好的是它不能计算对并限制引号。讨价还价有双引号,双引号,单引号和单引号转义。 这里只是一些有趣的preg函数。

$str=preg_replace('@//.*@','',$str);//delete comments
$str=preg_replace('@\s*/>@','>',$str);//delete xhtml tag slash ( />)
$str=str_replace(array("\n","\r","\t"),"",$str);//delete escaped white spaces
$str=preg_replace("/<\?(.*\[\'(\w+)\'\].*)\?>/","?>$1<?",$str);//rewrite associated array to object
$str=preg_replace("/\s*([\{\[\]\}\(\)\|&;]+)\s*/","$1",$str);//delete white spaces between brackets
$count=preg_match_all("/(\Wvar (\w{3,})[ =])/", $str, $matches);//find var names
$x=65;$y=64;
for($i=0;$i<$count;$i++){
   if($y+1>90){$y=65;$x++;}//count upper case alphabetic ascii code
   else $y++;
   $str=preg_replace("/(\W)(".$matches[$i]."=".$matches[$i]."\+)(\W)/","$1".chr($x).chr($y)."+=$3",$str);//replace 'longvar=longvar+'blabla' to AA+='blabla' 
   $str=preg_replace("/(\W)(".$matches[$i].")(\W)/","$1".chr($x).chr($y)."$3",$str);//replace all other vars
   }
//echo or save $str.
?>

您可以使用函数名称执行类似操作:

$count= preg_match_all("/function (\w{3,})/", $str, $matches);

如果要查看替换的变量,请将以下代码放在for循环中:

echo chr($x).chr($y)."=".$matches[$i]."<br>";

通过以下方式将PHP与JS分开:

 $jsphp=(array)preg_split("/<\?php|\?>/",$str);
 for($i=0;$i<count($jsphp);$i++){
    if($i%2==0){do something whith js clause}
    else {do something whith PHP clause}
    }

这只是一个草案。我总是很乐意接受建议。 希望是Englisch ......

答案 2 :(得分:1)

与Jan或B.F的回答相比,我通过橙色异常在这个Gist上的表现更好。

preg_replace('#(?s)\s|/\*.*?\*/|//[^\r\n]*#', '', $javascript);

https://gist.github.com/orangexception/1301150/ed16505e2cb200dee0b0ab582ebbc67d5f060fe8

答案 3 :(得分:-1)

适应于B.F.答案以及其他一些搜索和测试。它可以满足我的需要,足够快,等等。它的确使我引用的文本(最终)不存在。

class Developer {
   constructor(firstName, lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
   }

   getName() {
      return this.firstName + ' ' + this.lastName;
   }
}

let x = new Developer('Bob', 'Russ');

console.log(x.getName())
console.log(x)