簡體   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