RegEx pour la correspondance / remplacement des commentaires JavaScript (multiligne et en ligne)

Je dois supprimer tous les commentaires JavaScript d'une source JavaScript en utilisant l'objet JavaScript RegExp.

Ce dont j'ai besoin, c'est le modèle du RegExp.

Jusqu'à présent, j'ai trouvé ceci:

compressed = compressed.replace(/\/\*.+?\*\/|\/\/.*(?=[\n\r])/g, ''); 

Ce modèle fonctionne correctement pour:

 /* I'm a comment */ 

ou pour:

 /* * I'm a comment aswell */ 

Mais ne semble pas fonctionner pour l'inline:

 // I'm an inline comment 

Je ne suis pas un expert pour RegEx et ses modèles, alors j'ai besoin d'aide.

En outre, j'aimerais avoir un modèle RegEx qui supprime tous ces commentaires HTML.

 <!-- HTML Comment //--> or <!-- HTML Comment --> 

Et aussi ces commentaires HTML conditionnels qui peuvent être trouvés dans diverses sources JavaScript.

Merci

essaye ça,

 (\/\*[\w\'\s\r\n\*]*\*\/)|(\/\/[\w\s\']*)|(\<![\-\-\s\w\>\/]*\>) 

devrait marcher 🙂 Entrez la description de l'image ici

REMARQUE: Regex n'est pas un lexer ou un analyseur . Si vous avez un cas de bord étrange où vous avez besoin de commentaires bizarrement imbriqués issus d'une chaîne, utilisez un analyseur. Pour les autres 98% du temps, ce regex devrait fonctionner.

J'ai eu des commentaires de blocs assez complexes avec des astérisques imbriqués, des barres obliques, etc. L'expression régulière sur le site suivant a fonctionné comme un charme:

http://upshots.org/javascript/javascript-regexp-to-remove-comments
(Voir ci-dessous pour l'original)

Certaines modifications ont été apportées, mais l'intégrité du regex original a été conservée. Afin de permettre certaines séquences double-barre ( // ) (telles que les URL), vous devez utiliser la référence retour $1 dans votre valeur de remplacement au lieu d'une chaîne vide . C'est ici:

 /\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm // JavaScript: // source_string.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '$1'); // PHP: // preg_replace("/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/m", "$1", $source_string); 

DEMO: http://www.regextester.com/?fam=96247

CAS DE FONCTIONNEMENT: Il y a quelques cas où ce regex échoue. Une liste en cours de ces cas est documentée dans cet esprit public . Veuillez mettre à jour l'essentiel si vous pouvez trouver d'autres cas.

… et si vous souhaitez également supprimer <!-- html comments --> utilisez ceci:

 /\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*|<!--[\s\S]*?-->$/ 

(Original – pour référence historique seulement)

 /(\/\*([\s\S]*?)\*\/)|(\/\/(.*)$)/gm 

Je pose une expression qui doit faire quelque chose de similaire.
Le produit fini est:

 /(?:((["'])(?:(?:\\\\)|\\\2|(?!\\\2)\\|(?!\2).|[\n\r])*\2)|(\/\*(?:(?!\*\/).|[\n\r])*\*\/)|(\/\/[^\n\r]*(?:[\n\r]+|$))|((?:=|:)\s*(?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/))|((?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/)[gimy]?\.(?:exec|test|match|search|replace|split)\()|(\.(?:exec|test|match|search|replace|split)\((?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/))|(<!--(?:(?!-->).)*-->))/g 

Effrayant à droite?

Pour décomposer, la première partie correspond à n'importe quoi en guillemets simples ou doubles
Ceci est nécessaire pour éviter de faire correspondre les chaînes citées

 ((["'])(?:(?:\\\\)|\\\2|(?!\\\2)\\|(?!\2).|[\n\r])*\2) 

La deuxième partie correspond à des commentaires multilignes délimités par / * * /

 (\/\*(?:(?!\*\/).|[\n\r])*\*\/) 

La troisième partie correspond à des commentaires en une seule ligne commençant n'importe où dans la ligne

 (\/\/[^\n\r]*(?:[\n\r]+|$)) 

La quatrième à la sixième partie correspond à n'importe quoi dans un littéral regex
Cela repose sur un signe d'égal à égal précédent ou le caractère littéral avant ou après un appel regex

 ((?:=|:)\s*(?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/)) ((?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/)[gimy]?\.(?:exec|test|match|search|replace|split)\() (\.(?:exec|test|match|search|replace|split)\((?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/)) 

Et le septième que j'ai à l'origine oublié, supprime les commentaires html

 (<!--(?:(?!-->).)*-->) 

J'ai eu un problème avec mon environnement dev générant des erreurs pour un regex qui a brisé une ligne, donc j'ai utilisé la solution suivante

 var ADW_GLOBALS = new Object ADW_GLOBALS = { quotations : /((["'])(?:(?:\\\\)|\\\2|(?!\\\2)\\|(?!\2).|[\n\r])*\2)/, multiline_comment : /(\/\*(?:(?!\*\/).|[\n\r])*\*\/)/, single_line_comment : /(\/\/[^\n\r]*[\n\r]+)/, regex_literal : /(?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/)/, html_comments : /(<!--(?:(?!-->).)*-->)/, regex_of_doom : '' } ADW_GLOBALS.regex_of_doom = new RegExp( '(?:' + ADW_GLOBALS.quotations.source + '|' + ADW_GLOBALS.multiline_comment.source + '|' + ADW_GLOBALS.single_line_comment.source + '|' + '((?:=|:)\\s*' + ADW_GLOBALS.regex_literal.source + ')|(' + ADW_GLOBALS.regex_literal.source + '[gimy]?\\.(?:exec|test|match|search|replace|split)\\(' + ')|(' + '\\.(?:exec|test|match|search|replace|split)\\(' + ADW_GLOBALS.regex_literal.source + ')|' + ADW_GLOBALS.html_comments.source + ')' , 'g' ); changed_text = code_to_test.replace(ADW_GLOBALS.regex_of_doom, function(match, $1, $2, $3, $4, $5, $6, $7, $8, offset, original){ if (typeof $1 != 'undefined') return $1; if (typeof $5 != 'undefined') return $5; if (typeof $6 != 'undefined') return $6; if (typeof $7 != 'undefined') return $7; return ''; } 

Cela retourne tout ce qui est capturé par le texte de la chaîne cité et tout ce qui se trouve dans un littéral regex intact mais renvoie une chaîne vide pour toutes les captures de commentaires.

Je sais que c'est excessif et plutôt difficile à maintenir, mais il semble que cela fonctionne pour moi jusqu'à présent.

C'est tard pour être très utile à la question initiale, mais peut-être que cela aidera quelqu'un.

Sur la base de la réponse de @Ryan Wheale, j'ai trouvé que cela fonctionnait comme une capture complète pour s'assurer que les matches excluent tout ce qui se trouve dans un littéral de chaîne.

 /(?:\r\n|\n|^)(?:[^'"])*?(?:'(?:[^\r\n\\']|\\'|[\\]{2})*'|"(?:[^\r\n\\"]|\\"|[\\]{2})*")*?(?:[^'"])*?(\/\*(?:[\s\S]*?)\*\/|\/\/.*)/g 

Le dernier groupe (tous les autres sont mis au rebut) est basé sur la réponse de Ryan. Exemple ici .

Cela suppose que le code est bien structuré et valide javascript.

Remarque: cela n'a pas été testé sur un code mal structuré qui peut ou non être récupérable en fonction des heuristiques du moteur javascript.

Note: ceci devrait contenir pour le javascript valide <ES6, cependant, ES6 permet des littéralités de chaînes multi-lignes , auquel cas cette regex se cassera presque certainement, même si ce cas n'a pas été testé.


Cependant, il est encore possible de faire correspondre quelque chose qui ressemble à un commentaire dans un littérature regex (voir les commentaires / résultats dans l'exemple ci-dessus).

J'utilise la capture ci-dessus après avoir remplacé tous les littératures regex en utilisant la capture complète suivante extraite de es5-lexer ici et ici , comme indiqué dans la réponse de Mike Samuel à cette question :

 /(?:(?:break|case|continue|delete|do|else|finally|in|instanceof|return|throw|try|typeof|void|[+]|-|[.]|[/]|,|[*])|[!%&(:;<=>?[^{|}~])?(\/(?![*/])(?:[^\\\[/\r\n\u2028\u2029]|\[(?:[^\]\\\r\n\u2028\u2029]|\\(?:[^\r\n\u2028\u2029ux]|u[0-9A-Fa-f]{4}|x[0-9A-Fa-f]{2}))+\]|\\(?:[^\r\n\u2028\u2029ux]|u[0-9A-Fa-f]{4}|x[0-9A-Fa-f]{2}))*\/[gim]*)/g 

Pour l'exhaustivité, voir aussi cette mise en garde insignifiante .

Cela fonctionne pour presque tous les cas:

 var RE_BLOCKS = new RegExp([ /\/(\*)[^*]*\*+(?:[^*\/][^*]*\*+)*\//.source, // $1: multi-line comment /\/(\/)[^\n]*$/.source, // $2 single-line comment /"(?:[^"\\]*|\\[\S\s])*"|'(?:[^'\\]*|\\[\S\s])*'/.source, // - string, don't care about embedded eols /(?:[$\w\)\]]|\+\+|--)\s*\/(?![*\/])/.source, // - division operator /\/(?=[^*\/])[^[/\\]*(?:(?:\[(?:\\.|[^\]\\]*)*\]|\\.)[^[/\\]*)*?\/[gim]*/.source ].join('|'), // - regex 'gm' // note: global+multiline with replace() need test ); // remove comments, keep other blocks function stripComments(str) { return str.replace(RE_BLOCKS, function (match, mlc, slc) { return mlc ? ' ' : // multiline comment (replace with space) slc ? '' : // single/multiline comment match; // divisor, regex, or string, return as-is }); } 

Le code est basé sur regexes de jspreproc, j'ai écrit cet outil pour le compilateur anti – émeutes .

Voir http://github.com/aMarCruz/jspreproc

Si vous cliquez sur le lien ci-dessous, vous trouvez un script de suppression de commentaire écrit en regex.

Ce sont 112 lignes hors code qui fonctionnent ensemble fonctionne également avec mootools et Joomla et Drupal et d'autres sites Web cms. L'a testé sur 800 000 lignes de code et de commentaires. Fonctionne bien. Celui-ci sélectionne également plusieurs parenthèses comme (abc (/ nn / ('/ xvx /')) "// ligne de test") et les commentaires qui se situent entre des deux-points et les protègent. 23-01-2016 …! C'est le code avec les commentaires.

Cliquez ici

Basé sur les tentatives ci-dessus et en utilisant UltraEdit, principalement Abhishek Simon, j'ai trouvé cela fonctionner pour les commentaires en ligne et gère tous les personnages dans le commentaire.

 (\s\/\/|$\/\/)[\w\s\W\S.]* 

Ceci correspond aux commentaires au début de la ligne ou à un espace avant //

// public static final String LETTERS_WORK_FOLDER = "/ Letters / Generated / Work";

mais non

"http://schemas.us.com.au/hub/ '>" +

Donc ce n'est pas bon pour quelque chose comme

If (x) {f (x)} // où f est une fonction

Il suffit d'être

If (x) {f (x)} // où f est la fonction