Как я могу откомментировать код JavaScript с помощью этого preg_replace? - PullRequest
1 голос
/ 02 марта 2011

Я пытаюсь разложить мой // comments в моем JavaScript с помощью php preg_replace () и создал preg_replace, который должен выполнить следующее:

1.Когда комментарий начинается с новой строки, удалите всю эту строку: // COMMENTS .....

2. Когда комментарий находится на полпути позади скрипта, после 1 TAB // удаляем эту часть комментария exampleScript(); // (1space) comments

3.Не соответствует // в http://

Это предварительное место выполняет вышеуказанную работу, ОДНАКО, в настоящее время оно удаляет 3 строки кода с //. (см. Заголовок ложных совпадений ниже), которое следует пропустить.

$buffer = preg_replace('/(?<!http:)\/\/\s*[^\r\n]*/', '', $buffer);

хорошие совпадения

//something

// something *!&~@#^hjksdhaf

функция (); // comment

ложных совпадений

(/\/\.\//)
"//"  
"://"  

Итак, Как я могу отфильтровать эти три ложных совпадения и как изменить приведенное ниже регулярное выражение?

(?<!http:)\/\/\s*[^\r\n]*

PS, я не хочу использовать чужие минифайеры / каркасы кода с их собственными издержками. Пока только мое.

Ответы [ 3 ]

6 голосов
/ 02 марта 2011

Грамматика JavaScript - это не зависящая от контекста грамматика (я думаю, что она LL (1) -парсируемая). Его нельзя анализировать с помощью регулярных выражений.

В теории формальных языков в теории вычислимости есть результат, известный как лемма накачки, которая доказывает, что вы не можете анализировать произвольные контекстно-свободные грамматикис регулярным выражением.

Суть проблемы заключается в следующем: вы не можете просто искать строку //, потому что она может содержаться внутри другого действительного кода, например, строки.Вы не можете просто искать // внутри двух кавычек, потому что тогда вы получите ложные срабатывания, такие как alert('no!') // can't do it, где текст ) // can технически содержится между двумя ' знаками.Вместо этого вам нужно будет определить, где начинаются и заканчиваются строки.Хуже того, один тип строк может быть вложен в другой тип строк, а строки (даже полуоткрытые строки) могут быть вложены в комментарии!

Не существует простого общего решения - синтаксические элементы JavaScript, такие как строки, скобки, скобки и т. д. могут быть вложены в произвольно много уровней.Единственный способ точно определить, где начинается и заканчивается любой синтаксический элемент, - это правильно проанализировать все синтаксические элементы, с которыми вы можете столкнуться на этом пути.

Правильный ответ - использовать реальный синтаксический анализатор..

6 голосов
/ 02 марта 2011

Почему бы не использовать существующий ранее JavaScript-ограничитель, например YUI Compressor (PHP-привязки здесь )?


Если вы действительно настроены на написание своегоСобственно, посмотрите исходный код , чтобы увидеть, как это делается.
Краткая версия: правильный путь - использовать правильный подход парсер / токенизатор.

1 голос
/ 02 марта 2011
$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

...