Простой поиск по регулярному выражению и замена в php для минимизации / сжатия JavaScript? - PullRequest
7 голосов
/ 14 мая 2011

Можете ли вы опубликовать поиск и замену регулярных выражений в 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?

Ответы [ 2 ]

4 голосов
/ 18 мая 2011

Простое регулярное выражение для минимизации / сжатия javascript вряд ли будет где-либо существовать.Вероятно, есть несколько веских причин для этого, но вот несколько из этих причин:

Разрывы строк и точки с запятой Хорошие мини-разделители javascript удаляют все дополнительные разрывы строк, но поскольку механизмы javascript будут работать безточки с запятой в конце каждого оператора, минификатор может легко сломать этот код, если он не достаточно сложен для отслеживания и обработки различных стилей кодирования.

Динамические языковые конструкции Многие из хороших миниатюр javascriptavailable также изменит имена ваших переменных и функций для минимизации кода.Например, функция с именем strip_white_space, которая вызывается в вашем файле 12 раз, может быть переименована в простую «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» и сослались на него с той же точечной нотацией.

Параметры без регулярных выражений Несколько проектовсуществуют, чтобы решить эту проблему, используя более сложные решения, чем просто регулярное выражение, но многие из них не предпринимают никаких попыток изменить имена переменных, поэтому я все еще придерживаюсь упаковщика Дина Эдвардса или ДугласаJSMin Крокфорда или что-то вроде компрессора YUI .

Реализация PHP JSMin Дугласа Крокфорда

https://github.com/mrclay/minify

1 голос
/ 24 февраля 2012

Я пишу свой собственный минификатор, потому что у меня немного 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}
    }

Это всего лишь черновик.Я всегда рад за предложения.Надеюсь, это был английский ...

...