php 中用于缩小/压缩 javascript 的简单正则表达式搜索和替换?

发布于 2024-11-07 00:41:08 字数 1171 浏览 0 评论 0原文

您可以在 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 的示例又如何呢?

Can you post a regex search and replacement in php for minifying/compressing javascript?

For example, here's a simple one for 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();

And here's one for 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>

But what about one for javascript?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

拥抱影子 2024-11-14 00:41:08

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

换行符和分号
好的 javascript 压缩器会删除所有额外的换行符,但由于 javascript 引擎在每个语句末尾没有分号的情况下也可以工作,因此压缩器很容易破坏此代码,除非它足够复杂以监视和处理不同的编码风格。

动态语言结构
许多可用的优秀 JavaScript 压缩器也会更改变量和函数的名称以压缩代码。例如,在文件中调用 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
}

这都是有效的代码。但是,缩小器如何知道要替换什么?第一个“length”前面有“var”(但不是必须),但“height”前面只有一个逗号。如果缩小器足够聪明,可以正确替换第一个“长度”,那么当用作数组的属性时,它必须知道如何不更改单词“长度”?如果您定义了一个 JavaScript 对象,其中专门定义了“length”属性并使用相同的点符号引用它,那么事情会变得更加复杂。

非正则表达式选项 有几个项目使用比简单的正则表达式更复杂的解决方案来解决这个问题,但其中许多项目没有尝试更改变量名称,所以我仍然坚持使用 Dean Edwards 的打包程序Douglas Crockford 的 JSMin 或类似 YUI 压缩机。

Douglas Crockford 的 JSMin 的 PHP 实现

https://github.com/mrclay/minify

A simple regex for minifying/compressing javascript is unlikely to exist anywhere. There are probably several good reasons for this, but here are a couple of these reasons:

Line breaks and semicolons
Good javascript minifiers remove all extra line breaks, but because javascript engines will work without semicolons at the end of each statement, a minifier could easily break this code unless it is sophisticated enough to watch for and handle different coding styles.

Dynamic Language Constructs
Many of the good javascript minifiers available will also change the names of your variables and functions to minify the code. For instance, a function named 'strip_white_space' that is called 12 times in your file might be renamed simple 'a', for a savings of 192 characters in your minified code. Unless your file has a lot of comments and/or whitespace, optimizations like these are where the majority of your filesize savings will come from.

Unfortunately, this is much more complicated than a simple regex should try to handle. Say you do something as simple as:

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
}

This is all valid code. BUT, how does the minifier know what to replace? The first "length" has "var" before it (but it doesn't have to), but "height" just has a comma before it. And if the minifier is smart enough to replace the first "length" properly, how smart does it have to be know NOT to change the word "length" when used as a property of the array? It would get even more complicated if you defined a javascript object where you specifically defined a "length" property and referred to it with the same dot-notation.

Non-regex Options Several projects exist to solve this problem using more complex solutions than just a simple regex, but many of them don't make any attempt to change variable names, so I still stick with Dean Edwards' packer or Douglas Crockford's JSMin or something like the YUI Compressor.

PHP implementation of Douglas Crockford's JSMin

https://github.com/mrclay/minify

爱*していゐ 2024-11-14 00:41:08

我对 OrangeException 的 Gist 的了解比 Jan 或 BF 的答案更好。

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

https://gist.github.com/orangexception/1301150/ed16505e2cb200dee0b0ab582ebbc67d5 f060fe8

I had a better shot at this Gist by orangeexception than Jan or B.F's answers.

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

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

念﹏祤嫣 2024-11-14 00:41:08

我正在自己的压缩器上编写,因为我里面有一些 PHP
还有一个问题没有解决。 Preg_replace 无法将引号作为边界处理,或者更好的是,它不能对引号进行计数并削弱引号。讨价还价中有双引号、转义双引号、单引号和转义单引号。
这里只是一些有趣的 preg-functions。

$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}
    }

这只是一个草案。我总是很高兴收到建议。
希望是英文的...

I'm writing on my own minifier because I have some PHP inside.
There is still one not solved problem. Preg_replace cannot handle quotes as boundary, or better it cannot count pair and impair quotes. Into the bargain there are double quotes, escaped double quotes, single quotes and escaped single quotes.
Here are just some interesting preg-functions.

$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.
?>

You may do similarly with function names:

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

If you want to see the replaced vars, put the following code in the for-loop:

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

Separate php from JS by:

 $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}
    }

This is only a draft. I'm always happy for suggestions.
Hope it was Englisch...

瞄了个咪的 2024-11-14 00:41:08

改编自 BF 答案和其他一些搜索和测试,我得到了这个。它满足我的需要,足够快等等。它确实保留了我引用的文本(最后)。

   <?php $str=preg_replace('@//.*@','',$someScriptInPhpVar);//delete comments
    $count=preg_match_all("/(\Wvar (\w{3,})[ =])/", $str, $matches);//find var names
    $x=65;$y=96;
    for($i=0;$i<$count;$i++){if($y+1>122){$y=97;$x++;} else $y++; //count upper lower case alphabetic ascii code
    $str=preg_replace("/([^\"a-zA-Z])(".$matches[2][$i]."=".$matches[2][$i]."\+)(\W)/","$1".chr($x).chr($y)."+=$3",$str);//replace 'longvar=longvar+'blabla' to AA+='blabla'
    $str=preg_replace("/(\b)(".$matches[2][$i].")(\b)(?![\"\'\w :])/","$1".chr($x).chr($y)."$3",$str);//replace all other vars
    }
    $str=preg_replace("/\s+/"," ",$str);
    $someScriptInPhpVar=str_replace(array("\n","\r","\t","; ","} "),array("","","",";","}"),$str);//delete escaped white space and other space ?>

Adapted from B.F. answer and some other searching and testing I got to this. It works for my needs, is fast enough etc. It does leave my quoted text alone(finally).

   <?php $str=preg_replace('@//.*@','',$someScriptInPhpVar);//delete comments
    $count=preg_match_all("/(\Wvar (\w{3,})[ =])/", $str, $matches);//find var names
    $x=65;$y=96;
    for($i=0;$i<$count;$i++){if($y+1>122){$y=97;$x++;} else $y++; //count upper lower case alphabetic ascii code
    $str=preg_replace("/([^\"a-zA-Z])(".$matches[2][$i]."=".$matches[2][$i]."\+)(\W)/","$1".chr($x).chr($y)."+=$3",$str);//replace 'longvar=longvar+'blabla' to AA+='blabla'
    $str=preg_replace("/(\b)(".$matches[2][$i].")(\b)(?![\"\'\w :])/","$1".chr($x).chr($y)."$3",$str);//replace all other vars
    }
    $str=preg_replace("/\s+/"," ",$str);
    $someScriptInPhpVar=str_replace(array("\n","\r","\t","; ","} "),array("","","",";","}"),$str);//delete escaped white space and other space ?>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文