Как убрать комментарии из Javascript, используя переполнение стека

Я хочу удалить комментарии из этих сценариев:

var stName = "MyName"; //I WANT THIS COMMENT TO BE REMOVED
var stLink = "http://domain.com/mydomain";
var stCountry = "United State of America";

Каковы (лучшие) способы сделать это с помощью PHP?

0

Решение

Лучший способ — использовать реальный парсер или написать хотя бы лексер самостоятельно.
Проблема с Regex в том, что он становится чрезвычайно сложным, если вы принимаете все, что вам нужно.
Например, Кагатай Улубайпредложил Regex’es /\/\/[^\n]?/ а также /\/\*(.*)\*\// будет соответствовать комментариям, но они также будут соответствовать намного больше, как

var a = '/* the contents of this string will be matches */';
var b = '// and here you will even get a syntax error, because the entire rest of the line is removed';
var c = 'and actually, the regex that matches multiline comments will span across lines, removing everything between the first "/*" and here: */';
/*
this comment, however, will not be matched.
*/

Несмотря на то, что строки, содержащие такие последовательности, маловероятны, проблема реальная с встроенным регулярным выражением:

var regex = /^something.*/; // You see the fake "*/" here?

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

  • Обычный код, который вам нужно вывести снова, и где начало комментария может быть всего на расстоянии одного символа.
  • Комментарии, которые вы отбрасываете.
  • Литералы, которые вы также должны вывести, но там, где комментарий не может начинаться.

Теперь единственные литералы, о которых я могу думать, это строки (одинарные и двойные кавычки), встроенные регулярные выражения и строки шаблонов (обратные ссылки), но это могут быть не все.
И, конечно, вы также должны учитывать escape-последовательности внутри этих литералов, потому что вы можете встретить встроенное регулярное выражение типа

/^file:\/\/\/*.+/

в котором односимвольный лексер будет видеть только регулярное выражение /^file:\/ и неправильно разбирать следующее /*.+ как начало многострочного комментария.
Поэтому при встрече со вторым /, вы должны оглянуться назад и проверить, был ли последний символ, который вы передали \, То же самое касается всех видов кавычек для строк.

1

Другие решения

Я бы пошел с preg_replace (). Предполагая, что все комментарии являются однострочными комментариями (// Комментарий здесь), вы можете начать с этого:

$JsCode = 'var stName = "MyName isn\'t \"Foobar\""; //I WANT THIS COMMENT TO BE REMOVED
var stLink = "http://domain.com/mydomain"; // Comment
var stLink2 = \'http://domain.com/mydomain\'; // This comment goes as well
var stCountry = "United State of America"; // Comment here';

$RegEx = '/(["\']((?>[^"\']+)|(?R))*?(?<!\\\\)["\'])(.*?)\/\/.*$/m';
echo preg_replace($RegEx, '$1$3', $JsCode);

Выход:

var stName = "MyName isn't \"Foobar\"";
var stLink = "http://domain.com/mydomain";
var stLink2 = 'http://domain.com/mydomain';
var stCountry = "United State of America";

Это решение далеко от совершенства и может иметь проблемы со строками, содержащими «//» в них.

0

По вопросам рекламы [email protected]