您可以在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怎么样?
用于缩小/压缩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
}
这是所有有效的代码。但是,粉碎机如何知道要更换什么?第一个“长度”前面有“ var”(但不是必须),但是“高度”前面只有逗号。并且,如果minifier足够聪明,可以正确替换第一个“ length”,那么当用作数组的属性时,不更改“ length”一词,又有多聪明?如果您定义了一个javascript对象(其中专门定义了“ length”属性,并使用相同的点符号引用它),它将变得更加复杂。
非正则表达式选项存在多个项目,它们使用的解决方案比简单的正则表达式还要复杂,但是其中许多项目并未尝试更改变量名,因此我仍然坚持使用Dean Edwards' packer或Douglas Crockford's JSMin或类似YUI Compressor的东西。
我正在使用自己的压缩程序,因为我有内置一些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>";
通过以下方式将JS与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}
}
这只是草稿。我总是很高兴提出建议。希望那是英语...
根据B.F.的答案以及其他一些搜索和测试改编而成。它可以满足我的需要,足够快,等等。它的确使我引用的文本(最终)不存在。
<?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 ?>