繁体   English   中英

全面的RegExp删除JavaScript注释

[英]Comprehensive RegExp to remove JavaScript comments

我需要使用单个正则表达式可靠地删除所有JavaScript注释。

我搜索了StackOverflow和其他站点,但没有一个站点考虑到交替引号,多行注释,字符串内的注释,正则表达式等。

是否有任何正则表达式可以从中删除注释:

var test = [
    "// Code",
    '// Code',
    "'// Code",
    '"// Code',
    //" Comment",
    //' Comment',
    /* Comment */
    // Comment /* Comment
    /* Comment
     Comment // */ "Code",
    "Code",
    "/* Code */",
    "/* Code",
    "Code */",
    '/* Code */',
    '/* Code',
    'Code */',
    /* Comment
    "Comment",
    Comment */ "Code",
    /Code\/*/,
    "Code */"
]

这是一个jsbinjsfiddle进行测试。

我喜欢挑战:)

这是我的工作解决方案:

/((["'])(?:\\[\s\S]|.)*?\2|\/(?![*\/])(?:\\.|\[(?:\\.|.)\]|.)*?\/)|\/\/.*?$|\/\*[\s\S]*?\*\//gm

将其替换为$1

在这里提琴: http : //jsfiddle.net/LucasTrz/DtGq8/6/

当然,正如无数次指出的那样,适当的解析器可能会更好,但是仍然...

注意:我在装了正则表达式字符串的小提琴中使用了正则表达式文字,过多的转义会破坏您的大脑。


分解

((["'])(?:\\[\s\S]|.)*?\2|\/(?![*\/])(?:\\.|\[(?:\\.|.)\]|.)*?\/) <-- the part to keep
|\/\/.*?$                                                         <-- line comments
|\/\*[\s\S]*?\*\/                                                 <-- inline comments

保留的部分

(["'])(?:\\[\s\S]|.)*?\2                   <-- strings
\/(?![*\/])(?:\\.|\[(?:\\.|.)\]|.)*?\/     <-- regex literals

弦乐

    ["']              match a quote and capture it
    (?:\\[\s\S]|.)*?  match escaped characters or unescpaed characters, don't capture
    \2                match the same type of quote as the one that opened the string

正则表达式文字

    \/                          match a forward slash
    (?![*\/])                   ... not followed by a * or / (that would start a comment)
    (?:\\.|\[(?:\\.|.)\]|.)*?   match any sequence of escaped/unescaped text, or a regex character class
    \/                          ... until the closing slash

删除部分

|\/\/.*?$              <-- line comments
|\/\*[\s\S]*?\*\/      <-- inline comments

行注释

    \/\/         match two forward slashes
    .*?$         then everything until the end of the line

内联评论

    \/\*         match /*
    [\s\S]*?     then as few as possible of anything, see note below
    \*\/         match */

我必须使用[\\s\\S]而不是. 因为不幸的是JavaScript不支持regex s修饰符(单行-此行也允许.也匹配换行符)

此正则表达式将在以下特殊情况下工作:

  • 在字符类中包含/表达式模式: /[/]/
  • 字符串文字中的换行符

最后的老板打架

只是为了好玩 ...这是令人眼花 hard乱的硬核版本:

/((["'])(?:\\[\s\S]|.)*?\2|(?:[^\w\s]|^)\s*\/(?![*\/])(?:\\.|\[(?:\\.|.)\]|.)*?\/(?=[gmiy]{0,4}\s*(?![*\/])(?:\W|$)))|\/\/.*?$|\/\*[\s\S]*?\*\//gm

这将添加以下扭曲边缘的情况( fiddleregex101 ):

Code = /* Comment */ /Code regex/g  ; // Comment
Code = Code / Code /* Comment */ /g  ; // Comment    
Code = /Code regex/g /* Comment */  ; // Comment

这是一个极富启发性的代码,您可能不应该使用它(比以前的正则表达式要少得多),而要让这种情况变得很糟糕。

首先,我建议改为使用适当的JavaScript解析器。 检阅此先前的问答: JavaScript中的JavaScript解析器

对于您提供的输入1 ,这是一个可行的解决方案:

匹配模式:

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

这是模式的分解:

/
  (                                     # start match group 1
      "(?:[^\r\n\\"]|\\.)*"             #   match a double quoted string
    | '(?:[^\r\n\\']|\\.)*'             #   match a single quoted string
    | \/[^*\/]([^\\\/]|\\.)*\/[gm]*     #   match a regex literal
  )                                     # end match group 1
  | \/\/[^\r\n]*                        # match a single line break
  | \/\*[\s\S]*?\*\/                    # match a multi-line break
/g

并将其替换为$1 (匹配组1)。 这里的窍门是,组1中除了注释以外的所有内容都将被匹配,组1再次被替换为自身,但是注释被替换为空字符串。

这是一个regexr演示,显示了以下替换:

  var test = [
      "// Code",
      '// Code',
      "'// Code",
      '"// Code',




       "Code",
      "Code",
      "/* Code */",
      "/* Code",
      "Code */",
      '/* Code */',
      '/* Code',
      'Code */',
       "Code",
      /Code\/*/,
      "Code */"
  ]

1再者,解析器是必经之路,因为正则表达式文字可能会与除法运算符混淆。 如果您有类似var x = a / b / g;的赋值var x = a / b / g; 在您的源代码中,以上解决方案将失效!

我建议您先看一下使用自身的JavaScript解析器解析JavaScript,然后利用解析器API去除不需要的内容。 我个人没有这样做,但是正则表达式应该限于正则内容,我怀疑JS属于其中。

这是一些不错的地方。

JavaScript中的JavaScript解析器

是否有任何可删除注释的正则表达式

不可以。您不能构建将与注释匹配的正则表达式(这样您就可以简单地将匹配替换为空字符串),因为如果没有回首,就无法确定//"是注释还是字符串文字的结尾。

您可以使用正则表达式作为标记生成器(“仅”需要注意字符串文字,正则表达式文字和两种类型的注释),但是我建议您使用功能全面的JavaScript解析器,它们是免费提供的。

test.replace(/(/ *([\\ s \\ S] ?)* /)|(//(.$$)/ gm,'');

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM