用于匹配/替换JavaScript注释(多行和内联)的正则表达式

用于匹配/替换JavaScript注释(多行和内联)的正则表达式,javascript,regex,comments,replace,Javascript,Regex,Comments,Replace,我需要使用JavaScript RegExp对象从JavaScript源中删除所有JavaScript注释 我需要的是RegExp的模式 到目前为止,我发现: compressed = compressed.replace(/\/\*.+?\*\/|\/\/.*(?=[\n\r])/g, ''); 此模式适用于以下情况: /* I'm a comment */ 或: /* * I'm a comment aswell */ 但似乎不适用于内联: // I'm an inline comm

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

我需要的是RegExp的模式

到目前为止,我发现:

compressed = compressed.replace(/\/\*.+?\*\/|\/\/.*(?=[\n\r])/g, '');
此模式适用于以下情况:

/* I'm a comment */
或:

/*
 * I'm a comment aswell
*/
但似乎不适用于内联:

// I'm an inline comment
我对正则表达式和它的模式不是很精通,所以我需要帮助

另外,我希望有一个正则表达式模式,它可以删除所有类似HTML的注释

<!-- HTML Comment //--> or <!-- HTML Comment -->
还有那些条件HTML注释,可以在各种JavaScript源代码中找到

谢谢。

试试这个

(\/\*[\w\'\s\r\n\*]*\*\/)|(\/\/[\w\s\']*)|(\<![\-\-\s\w\>\/]*\>)
(\/\*[\w\'\s\r\n\*]*\*/)(\/\/[\w\s\']*)(\\/]*>)
应该有效:) 注意:。如果您有一些奇怪的边缘情况,需要从字符串中解析出一些奇怪的嵌套注释,请使用解析器。对于其他98%的时间,这个正则表达式应该可以工作。

我用嵌套的星号、斜杠等进行了相当复杂的块注释。以下站点上的正则表达式工作得非常出色:


(原件见下文)

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

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

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

// PHP:
// preg_replace("/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/m", "$1", $source_string);
演示:

失败的用例:此正则表达式失败的边缘案例很少。这些案例的持续列表记录在中。如果您能找到其他案例,请更新要点

…如果您还想删除
,请使用以下命令:

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

基于以上尝试,并使用UltraEdit,主要是Abhishek Simon,我发现它适用于内联注释并处理注释中的所有字符

(\s\/\/|$\/\/)[\w\s\W\S.]*
这将匹配行开头的注释或前面的空格//

//公用静态最终字符串字母\u工作\u文件夹= “/信件/生成/工作”

但不是

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

所以这对像这样的事情是不好的

if(x){f(x)}//其中f是某个函数

只是需要

if(x){f(x)}//其中f是函数


我一直在使用一个需要做类似事情的表达式。
成品为:

/(?:((["'])(?:(?:\\\\)|\\\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
第二部分匹配由/*分隔的多行注释*/

(\/\*(?:(?!\*\/).|[\n\r])*\*\/)
第三部分匹配从行中任意位置开始的单行注释

(\/\/[^\n\r]*(?:[\n\r]+|$))
第四到第六部分匹配正则表达式文本中的任何内容
这依赖于前面的等号或位于正则表达式调用之前或之后的文字

((?:=|:)\s*(?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/))
((?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/)[gimy]?\.(?:exec|test|match|search|replace|split)\()
(\.(?:exec|test|match|search|replace|split)\((?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/))
我最初忘记的第七个删除了html注释

(<!--(?:(?!-->).)*-->)
())*-->)
我的开发环境出现了一个问题,为一个中断了一行的正则表达式发出错误,所以我使用了以下解决方案

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 '';
}
var ADW_GLOBALS=新对象
ADW_全局={
引文:/([“'))(?:(?:\\\\\)\\\\\2 \\\\\\\\\\\\\\(?!\\\\2)。\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\(?!\2)。[\n\r])*\2)/,
多行注释:/(\/\*(?:(?!\*\/).\124;[\ n\r])*\*/,
单行注释:/(\/\/[^\n\r]*[\n\r]+)/,
正则表达式文字:/(?:\/(?:(?!\\*\/)。\\\\\\\\\\\\\\\\\\/\\\[(?:\\\\\\\\\\\\\]\\\[^]]+\]+\/,
html_注释:/())*-->/,
厄运规则:''
}
ADW_GLOBALS.regex_of_doom=new RegExp(
“(?:”+ADW_GLOBALS.quotes.source+“|”+
ADW_GLOBALS.multiline_comment.source+'|'+
ADW_GLOBALS.single_line_comment.source+'|'+
“((?:=|:)\\s*”+ADW_GLOBALS.regex_literal.source+)|”(“+
ADW|u GLOBALS.regex|u literal.source+'[gimy]?\\.(?:exec | test | match | search | replace | split)\\\('+'))|('+
“\\”(?:exec | test | match | search | replace | split)\\(“+ADW|u GLOBALS.regex|u literal.source+”)|”+
ADW_GLOBALS.html_comments.source+'),“g”
);
将代码改为测试。替换(ADW_GLOBALS.regex_of_doom,函数(匹配,$1,$2,$3,$4,$5,$6,$7,$8,偏移,原始){
如果(typeof$1!=“未定义”)返回$1;
如果(typeof$5!=“undefined”)返回$5;
如果(typeof$6!=“未定义”)返回$6;
如果(typeof$7!=“undefined”)返回$7;
返回“”;
}
这将返回由带引号的字符串文本捕获的任何内容以及在正则表达式文本中找到的任何内容,但会为所有注释捕获返回空字符串


我知道这是过分的,而且很难维持,但到目前为止,它似乎对我很有效。

这对于最初的问题来说太晚了,但也许它会帮助一些人

根据@Ryan Wheale的回答,我发现这是一个全面的捕获,以确保匹配排除在字符串文本中找到的任何内容

/(?:\r\n|\n|^)(?:[^'"])*?(?:'(?:[^\r\n\\']|\\'|[\\]{2})*'|"(?:[^\r\n\\"]|\\"|[\\]{2})*")*?(?:[^'"])*?(\/\*(?:[\s\S]*?)\*\/|\/\/.*)/g
最后一组(所有其他组均被丢弃)基于Ryan的答案。示例

这假设代码是结构良好且有效的javascript

注意:这还没有在结构不良的代码上测试过,这些代码可能会恢复,也可能不会恢复,这取决于javascript引擎自己的启发式

注意:这应该适用于有效的javascript
但是,仍然可以在正则表达式文本中匹配类似于注释的内容(请参见上面示例中的注释/结果)

在使用以下从es5 lexer中提取的全面捕获替换所有正则表达式文字后,我使用上述捕获,如在的回答中所述:

以下代码:::)以下以下以下代码::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::)最后::::::;在瞬间的实例中,瞬间发生发生发生发生发生发生发生发生发生的事件,返回;返回;返回;返回;返回;返回;扔扔扔;投掷;投掷;投掷;投掷;投掷;投掷;投掷;尝试;尝试;尝试;尝试;尝试;类型类型类型类型;类型类型类型的类型的类型的类型;类型;类型的;类型的;类型的;类型的;类型的;类型的;类型的;类型的;类型的;类型的;类型的;若若若若若若若若若若若若若若若若若若若若若若若若若若若若若若若8\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
有关完整性,请参见。

这适用于几乎所有情况:

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
  });
}
代码基于jsprep中的正则表达式
/(?:\r\n|\n|^)(?:[^'"])*?(?:'(?:[^\r\n\\']|\\'|[\\]{2})*'|"(?:[^\r\n\\"]|\\"|[\\]{2})*")*?(?:[^'"])*?(\/\*(?:[\s\S]*?)\*\/|\/\/.*)/g
/(?:(?: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
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
  });
}
my_string_or_obj.replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm, ' ')
let a = "hello /* ";
let b = 123;
let c = "world */ ";
/\*((.|\n)(?!/))+\*/