Удаление комментариев в JavaScript с использованием Ruby - PullRequest
1 голос
/ 02 апреля 2011

Мне нужно регулярное выражение или что-то еще, чтобы удалить такого рода комментарии.

/*!
 * Foo Bar
 */

Я пытался с /(\/*!.**\/)/m, но не удается. Любое предложение?

Ответы [ 7 ]

3 голосов
/ 02 апреля 2011

Чтобы сделать это точно и эффективно , есть лучшее регулярное выражение:

regexp = /\/\*![^*]*\*+(?:[^*\/][^*]*\*+)*\//
result = subject.gsub(regexp, '')

Джеффри Фридл подробно рассматривает эту конкретную проблему (на примере C-комментариев) в своей классической работе: Освоение регулярных выражений (3-е издание) . Вот разбивка регулярного выражения, иллюстрирующая «Развертывание в петле» техника эффективности.

regexp_long = / # Match she-bang style C-comment
    \/\*!       # Opening delimiter.
    [^*]*\*+    # {normal*} Zero or more non-*, one or more *
    (?:         # Begin {(special normal*)*} construct.
      [^*\/]    # {special} a non-*, non-\/ following star.
      [^*]*\*+  # More {normal*}
    )*          # Finish "Unrolling-the-Loop"
    \/          # Closing delimiter.
    /x
result = subject.gsub(regexp_long, '')

Обратите внимание, что этому регулярному выражению не нужен модификатор Ruby 'm' dot-match-all , поскольку он не использует точку!

Дополнительно: Итак, насколько эффективнее это регулярное выражение по сравнению с более простым /\/\*!.*?\*\//m выражением? Хорошо используя отладчик RegexBuddy , я измерил, сколько шагов каждое регулярное выражение предприняло, чтобы соответствовать комментарию. Вот результаты как для сопоставления, так и для несоответствия: (Для несоответствующего случая я просто удалил последний / из комментария)

/*!
 * This is the example comment
 * Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
 * Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
 * Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
 */

'
REGEX                        STEPS TO: MATCH  NON-MATCH
/\/\*!.*?\*\//m                        488      491
/\/\*![^*]*\*+(?:[^*\/][^*]*\*+)*\//    23       29
'

Как видите, решение с отложенными точками (которое должно возвращаться по одному разу для каждого символа в комментарии) гораздо менее эффективно. Также обратите внимание, что разница в эффективности еще более выражена при длинных и длинных комментариях.

CAVEAT Обратите внимание, что это регулярное выражение не будет выполнено, если разделитель открывания будет находиться внутри литеральной строки, например, Msgstr "В этой строке есть / *! Чтобы сделать это правильно со 100% точностью, вам потребуется полностью разобрать скрипт.

2 голосов
/ 02 апреля 2011

Вам нужно сбежать и от *:

/(\/\*!.*\*\/)/m

проверить это: http://www.rubular.com/r/n2bV9qUD6k

2 голосов
/ 02 апреля 2011

* должен быть экранирован, в противном случае он соответствует нулю или более вхождений / (в случае \/*).Также есть синтаксическая ошибка в .**.Попробуйте следующий RE с *, правильно экранированным:

/\/\*!.*?\*\//m
1 голос
/ 08 июня 2014

Простые регулярные выражения для удаления (в стиле c) однострочных и многострочных комментариев.Но обратите внимание, что они действительно просты - например, они не используют / * * / внутри строкового литерала.Но должно быть хорошо для удаления комментариев из простого кода:

str.gsub!(/\/\*.*?\*\//m, '') # remove multiline comments
str.gsub!(/\s*\/\/.*/, '') # remove single-line comments
0 голосов
/ 02 апреля 2011

Я бы настоятельно рекомендовал удалить этот комментарий с помощью Google Closure Compiler , я использовал его в производстве, и это фантастика.

0 голосов
/ 02 апреля 2011

Ну, я думаю, я получил то, что вы хотите :)

<html>
<head>
<title>Code Condenser</title>
<style type="text/css">
#source{font-size:10pt;width:90%;height:300px;}
body{text-align:center;}
</style>
<script type="text/javascript">
function vc_js_condenser(){var a=/[a-zA-Z0-9._'"]/;var b=/[a-zA-Z0-9._]/;var c=/[a-zA-Z0-9._\]\)"']/;
function d(e,f){e=e.replace(/[\n\r]+/g,"\n");var g=(typeof(f)=="boolean")?f:false;var h=["var","else",
"new","do","case","with","typeof","delete","try","finally","throw","in","instanceof"];var i=0;var j=
new Array();var k=e.split('');l=k.length;var m=new Array();var G=null;var o=false;var p=[["'","'","\\"]
,['"','"','\\'],["//","\n",null],["/*","*/",null]];var q="[](){},;/\n";var r;function s(){if(m.length<1)
return;var u=m.join('');if((!g)||((u.match(/^\/\//)==null)&&(u.match(/^\/\*/)==null))){if(!((u=="\n")&&
((G==';')||(G=="\n")))){if((G!=null)&&(G.match(a)!=null)&&(u.match(a)!=null))j[j.length]=' ';j[j.length]
=u;G=u;}}m.length=0;v=false;}var v=false;var w=false;while(i<l){if(!o){if((k[i]==" ")||(k[i]=="\t")){s();
}else{var x=false;if(q.indexOf(k[i])>-1){if(k[i]!='/'){x=true;s();}else if((m.length>0)&&(m[0]!='/')){
s();}}for(var y=0;y<p.length;y++){var z='';if((m.length>0)&&(m[m.length-1]==p[y][0].charAt(0)))z=m[
m.length-1];var A=z+k[i];if(A==p[y][0]){o=true;r=y;if(z!='')m.length--;if(m.length>0)s();if(z!='')m
[m.length]=z;break;}}if((k[i]=="/")&&(!o)&&(m.length==0)&&(G!=null)&&(G.match(c)==null)&&(i+1<k.length)
&&(k[i+1]!='/')){o=true;r=null;}var B=k[i].match(b)!=null;if(m.length<1)v=B;if(v!=B){s();v=B;}m[m.length]
=k[i];if(x)s();}}else{m[m.length]=k[i];var C=m.join('');if(r!=null){var D=C.lastIndexOf(p[r][1]);if((D!=-1)
&&(D>0)){if(m[D-1]==p[r][2]){if((D>2)&&(m[D-2]==p[r][2])){s();o=false;}}else{s();o=false;}}}else{if((w==false)
&&(k[i]=="/")){i++;while((i<k.length)&&(k[i].match(b)!=null)){m[m.length]=k[i];i++;}s();o=false;i--;}else{if
(!w&&(k[i]=="\\"))w=true;else w=false;}}}i++;}s();var E=-1;for(var i=0;i<j.length;i++){var u=j[i];var
F=(i>0)?j[i-1]:null;var n=(i<(j.length-1))?j[i+1]:null;if(u=="\n"){if((F!=null)&&(n!=null)){if((F.match(c)
!=null)&&(n.match(a)!=null)){u=';';for(var H=h.length-1;H>-1;H--){if(F==h[H])u=' ';}j[i]=u;E++;if((E<j.length)
&&(E>-1)&&(i!=E))j[E]=j[i];}}}else{E++;if((E<j.length)&&(E>-1)&&(i!=E))j[E]=j[i];}}j.length=E+1;return j;}var
I=document.getElementById('source');var J=I.value.length;I.value=d(I.value,document.getElementById('uncomment').checked
==true).join('');var K=I.value.length;var F=document.getElementById("saved");F.removeChild(F.firstChild);var
L=document.createElement("span");F.appendChild(L);L.appendChild(document.createTextNode("Original Size: "+
J+" characters"));L.appendChild(document.createElement("br"));L.appendChild(document.createTextNode(
"Condensed Size: "+K+" characters"));L.appendChild(document.createElement("br"));L.appendChild(
document.createTextNode("Size Difference: "+(J-K)+" characters"));if(J!=0){L.appendChild(document.createElement
("br"));L.appendChild(document.createTextNode("Condensed Code is "+(Math.floor(K/J*10000)/100)+
"% of original size."));}}
</script>
</head>
<body>
<h1>JavaScript Source Code Condenser</h1>
<p>Paste only valid Javascript (no HTML tags) in the box below.</p>
<button onclick="vc_js_condenser();">Condense Code</button>&nbsp;<input type="checkbox" checked="checked" id="uncomment" />Remove Comments&nbsp;<button onclick="document.getElementById('source').select();">Select All</button><br />
<textarea id="source"></textarea><br />
<p id="saved"><span></span></p>
</body>
</html>

Пожалуйста, сохраните этот скрипт как HTML, а затем запустите его в браузере, затем скопируйте свой javascript и поместите его в текстовое поле, а затем сожмите его кнопкой

Этот код удалит пробелы и комментарии в вашем коде, поэтому, пожалуйста, не забудьте завершить свои функции; чтобы избежать синтаксической ошибки.

Это поможет вам уменьшить размер ваших javascript-файлов, это поместит ваш javascript в 1 строку, поэтому, если вам это нужно, вы можете использовать это дополнение в Firefox, если вы его используете http://www.formatjavascript.com/

С уважением :) Пожалуйста, отметьте этот ответ как правильный, если вы считаете его полезным

0 голосов
/ 02 апреля 2011

Вы можете использовать сжатие JavaScript, такое как сжатие YUI или компилятор Google Closure

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...