Как я могу раскомментировать код JavaScript с помощью этого preg_replace?

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

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

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

3. Не совпадайте с // в http://

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

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

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

//something

// something *!&~@#^hjksdhaf

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

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

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

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

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

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


person Sam    schedule 02.03.2011    source источник


Ответы (3)


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


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

person Matt Ball    schedule 02.03.2011
comment
спасибо за комментарий, но я действительно хотел бы использовать свои собственные вещи сейчас - person Sam; 02.03.2011
comment
@Sam: ты не возражаешь, если я спрошу, почему? Вы используете это как учебный проект? В противном случае это звучит как синдром NIH. - person Matt Ball; 02.03.2011
comment
Первый: я учусь и сейчас нахожусь в эре подражания новичку. Я должен быть человеком IHBLRIA: Invented Here, But Let's Reinvent It Anyway - person Sam; 02.03.2011
comment
@Sam: Тогда вы сегодня усвоили важный урок: Прежде чем разрабатывать решение, убедитесь, что вы действительно понимаете проблему. - person Daniel Pryden; 02.03.2011

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

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

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

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

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

person Daniel Pryden    schedule 02.03.2011
comment
Спасибо Даниил или такая интересная теорема. Это превращает весь мой подход в шутку с точки зрения будущего. (опять же, пока работает без нареканий) - person Sam; 02.03.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

person Sam    schedule 02.03.2011