用于匹配/替换JavaScript注释的RegEx(多行和内联)

met*_*rce 38 javascript regex comments replace

我需要使用JavaScript RegExp对象从JavaScript源中删除所有JavaScript注释.

我需要的是RegExp的模式.

到目前为止,我发现了这个:

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

此模式适用于:

/* I'm a comment */
Run Code Online (Sandbox Code Playgroud)

或者:

/*
 * I'm a comment aswell
*/
Run Code Online (Sandbox Code Playgroud)

但似乎不适用于内联:

// I'm an inline comment
Run Code Online (Sandbox Code Playgroud)

我不是RegEx的专家和它的模式,所以我需要帮助.

另外,我想要一个RegEx模式,它将删除所有那些类似HTML的注释.

<!-- HTML Comment //--> or <!-- HTML Comment -->
Run Code Online (Sandbox Code Playgroud)

还有那些条件HTML注释,可以在各种JavaScript源中找到.

谢谢.

Rya*_*ale 69

注意:正则表达式不是词法分析器或解析器.如果您有一些奇怪的边缘情况,您需要从字符串中解析出一些奇怪的嵌套注释,请使用解析器.对于其他98%的时间,这个正则表达式应该工作.

我使用嵌套的星号,斜杠等进行了相当复杂的块注释.以下站点的正则表达式就像一个魅力:

http://upshots.org/javascript/javascript-regexp-to-remove-comments
(见下文原创)

已经进行了一些修改,但保留了原始正则表达式的完整性.为了允许某些双斜杠(//)序列(例如URL),必须$1在替换值中使用反向引用而不是空字符串.这里是:

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

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

// PHP:
// preg_replace("/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/m", "$1", $source_string);
Run Code Online (Sandbox Code Playgroud)

演示: http ://www.regextester.com/ ? fam = 96247

失败的使用案例:有一些边缘情况,这个正则表达式失败.这个公开要点记录了这些案例的持续列表.如果您能找到其他案例,请更新要点.

......如果你想删除<!-- html comments -->使用此:

/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*|<!--[\s\S]*?-->$/
Run Code Online (Sandbox Code Playgroud)

(原件 - 仅供参考)

// DO NOT USE THIS - SEE ABOVE
/(\/\*([\s\S]*?)\*\/)|(\/\/(.*)$)/gm
Run Code Online (Sandbox Code Playgroud)

  • `(?:\ /\*(?:[\ s\S]*?)\*\/)|(?:^\s*\/\/(?:.*)$)`应该更好它不会在字符串中间处理`//`,例如在urls中 (7认同)
  • @DG - 随意获取一个 javascript 解析器并将其用于您的极端情况。上面的正则表达式不是用于解析,而是用于删除文件中的典型注释。如果解析器过度使用,我建议您对斜杠 (/) 或星号 (*) 进行编码或使用连接:`"所有内容 /" + "* 在此字符串中 *" + "/ 应该被保留"` (2认同)
  • @RyanWheale - 冷静。我只是提醒其他人注意。它也会在 `foo = "this //is.no.comment"` 上失败。但最大的缺陷是它会剥离“;” 来自`ab=a+b; // AB`。原作没有,但原作者承认它有其他缺陷。顺便说一句,您建议的解决方法仅在我负责将被剥离的代码时才有用。如果是这样,我可以对自己施加各种限制,编写正则表达式将是微不足道的。尽管如此,我还没有找到完美的正则表达式解决方案。这可能(实际上)是不可能的。 (2认同)

abi*_*964 19

试试这个,

(\/\*[\w\'\s\r\n\*]*\*\/)|(\/\/[\w\s\']*)|(\<![\-\-\s\w\>\/]*\>)
Run Code Online (Sandbox Code Playgroud)

应该管用 :) 在此输入图像描述

  • 不要使用这个正则表达式!它还匹配`http://`和任何其他具有`//`或`/*`的正则表达式.所以它无法使用 (12认同)
  • 没有正则表达式的解决方案.您无法区分//这是否出现在代码(字符串)内部或行尾(无法计算引号字符的数字(获取偶数)("|"),因此只有在找到//注释之后) (9认同)
  • 这也将与http://中的//匹配,因此<img rel="nofollow noreferrer" src ="http://foo.com/foo_image.png"/>将被视为评论!哪不是! (6认同)
  • 那么"foo/*bar*/baz"怎么样? (5认同)

wol*_*ast 6

我一直在做一个需要做类似事情的表达.
成品是:

/(?:((["'])(?:(?:\\\\)|\\\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
Run Code Online (Sandbox Code Playgroud)

可怕吧?

为了分解它,第一部分匹配单引号或双引号内的任何内容
这是避免匹配引用字符串所必需的

((["'])(?:(?:\\\\)|\\\2|(?!\\\2)\\|(?!\2).|[\n\r])*\2)
Run Code Online (Sandbox Code Playgroud)

第二部分匹配由/**/分隔的多行注释

(\/\*(?:(?!\*\/).|[\n\r])*\*\/)
Run Code Online (Sandbox Code Playgroud)

第三部分匹配从行中的任何位置开始的单行注释

(\/\/[^\n\r]*(?:[\n\r]+|$))
Run Code Online (Sandbox Code Playgroud)

第四到第六部分匹配正则表达式文字中的任何内容
这取决于前面的等号或正则表达式之前或之后的文字

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

我最初忘记的第七个删除了html评论

(<!--(?:(?!-->).)*-->)
Run Code Online (Sandbox Code Playgroud)

我的开发环境发生了一个问题,因为正则表达式打破了一条线,因此我使用了以下解决方案

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 '';
}
Run Code Online (Sandbox Code Playgroud)

这将返回由引用的字符串文本捕获的任何内容以及在正则表达式文本中找到的任何内容,但返回所有注释捕获的空字符串.

我知道这是过度的,而且很难维护,但到目前为止它似乎对我有用.


aMa*_*ruz 5

这适用于几乎所有情况:

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
  });
}
Run Code Online (Sandbox Code Playgroud)

该代码基于 jspreproc 的正则表达式,我为riot 编译器编写了这个工具。

请参阅http://github.com/aMarCruz/jspreproc


小智 5

在简单的 JS 正则表达式中,这样:

my_string_or_obj.replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm, ' ')
Run Code Online (Sandbox Code Playgroud)