2

我正在尝试编写一个正则表达式(在 JavaScript 中),它将匹配 JS 文件开头的多行注释。

到目前为止,我想出了这个:/^(\/\*[^\*\/]*\*\/)/g

它适用于单行注释:http
://refiddle.com/24o 但我的问题是它不适用于多行注释:http ://refiddle.com/24m

您有任何解决方法的想法吗?

4

6 回答 6

4

HTML一样,JavaScript不能被正则表达式解析。试图正确地这样做是徒劳的。

相反,您必须使用将 JavaScript 源代码正确转换为AST的解析器,您可以通过编程方式对其进行检查。幸运的是,有一些库可以为您进行解析

这是一个输出此代码的 AST 的工作示例:

/* this is a
multi-line
comment */

var test = "this is a string, /* and this is not a comment! */";

// ..but this is

这让我们:

[
  "toplevel",
  [
    [
      {
        "name": "var",
        "start": {
          "type": "keyword",
          "value": "var",
          "line": 5,
          "col": 4,
          "pos": 57,
          "endpos": 60,
          "nlb": true,
          "comments_before": [
            {
              "type": "comment2",
              "value": " this is a\n    multi-line\n    comment ",
              "line": 1,
              "col": 4,
              "pos": 5,
              "endpos": 47,
              "nlb": true
            }
          ]
        },
        "end": {
          "type": "punc",
          "value": ";",
          "line": 5,
          "col": 67,
          "pos": 120,
          "endpos": 121,
          "nlb": false,
          "comments_before": []
        }
      },
      [
        [
          "test",
          [
            {
              "name": "string",
              "start": {
                "type": "string",
                "value": "this is a string, /* and this is not a comment! */",
                "line": 5,
                "col": 15,
                "pos": 68,
                "endpos": 120,
                "nlb": false,
                "comments_before": []
              },
              "end": {
                "type": "string",
                "value": "this is a string, /* and this is not a comment! */",
                "line": 5,
                "col": 15,
                "pos": 68,
                "endpos": 120,
                "nlb": false,
                "comments_before": []
              }
            },
            "this is a string, /* and this is not a comment! */"
          ]
        ]
      ]
    ]
  ]
]

现在只需遍历 AST 并提取您需要的内容即可。

于 2012-06-21T15:51:32.833 回答
2

您建议的正则表达式不起作用,因为*评论中有 a 。此外,它只会查找文件开头的注释。

尝试改用这个:

/\/\*[\s\S]*?\*\//
于 2012-06-21T15:19:39.970 回答
2

在这个链接上有一个很好的讨论这个问题。这对你有帮助吗?

他的解决方案是:

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

于 2012-06-21T15:23:18.970 回答
1

尝试

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

本页详细介绍了如何查找多行注释。

于 2012-06-21T15:21:31.013 回答
0

这是一个匹配任何多行或单行注释的注释:

/(\/\*.*?\*\/|\/\/[^\n]+)/

如果您只想要多行匹配,请放弃后半部分:

/\/\*.*?\*\//

对于这两个,请确保您s设置了标志,以便.匹配新行。

于 2012-06-21T15:21:38.987 回答
0

我不是 javascript 专家,但似乎必须考虑 C/C++ 注释。
正确完成意味着必须在过程中考虑报价(转义和所有这些)。

以下是两种有效的正则表达式方法。Regex 1 直接找到第一个C风格的注释,一匹配就找到了。正则表达式 2 是一般情况。它查找 C 样式、C++ 样式或非注释,是全局的,并允许您在找到所需内容时中断。

在这里测试http://ideone.com/i1UWr

代码

var js = '\
// /* C++ comment  */      \\\n\
   /* C++ comment (cont) */  \n\
/* t "h /* is"               \n\
 is first C-style /*         \n\
//  comment */               \n\
and /*second C-style*/       \n\
then /*last C-style*/        \n\
';

var cmtrx1 = /^(?:\/\/(?:[^\\]|\\\n?)*?\n|(?:"(?:\\[\S\s]|[^"\\])*"|'(?:\\[\S\s]|[^'\\])*'|[^\/"'\\]*))+(\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\/)/;

var cmtrx2 = /(\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\/)|(\/\/(?:[^\\]|\\\n?)*?)\n|(?:"(?:\\[\S\s]|[^"\\])*"|'(?:\\[\S\s]|[^'\\])*'|[\S\s][^\/"'\\]*)/g;

//
print ('Script\n===========\n'+js+'\n===========\n\n');

var match;
//
print ("Using Regex 1\n---------------\n");
if ((match=cmtrx1.exec( js )) != null)
    print ("Found C style comment:\n'" + match[1] + "'\n\n");
//
print ("Using Regex 2\n---------------\n");
while ((match=cmtrx2.exec( js )) != null)
{
   if (match[1] != undefined)
   {
        print ("- C style :\n'" + match[1] + "'\n");
        // break;     // uncomment to stop after first c-style match
   }
   // comment this to not print it
   if (match[2] != undefined)
   {
        print ("- C++ style :\n'" + match[2] + "'\n");
   }
}

输出

Script
===========
// /* C++ comment  */      \
   /* C++ comment (cont) */  
/* t "h /* is"               
 is first C-style /*         
//  comment */               
and /*second C-style*/       
then /*last C-style*/        

===========


Using Regex 1
---------------

Found C style comment:
'/* t "h /* is"               
 is first C-style /*         
//  comment */'


Using Regex 2
---------------

- C++ style :
'// /* C++ comment  */      \
   /* C++ comment (cont) */  '

- C style :
'/* t "h /* is"               
 is first C-style /*         
//  comment */'

- C style :
'/*second C-style*/'

- C style :
'/*last C-style*/'

扩展正则表达式

Regex 1:

/^(?:\/\/(?:[^\\]|\\\n?)*?\n|(?:"(?:\\[\S\s]|[^"\\])*"|'(?:\\[\S\s]|[^'\\])*'|[^\/"'\\]*))+(\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\/)/

     /^
     (?:
          \/\/
          (?: [^\\] | \\\n? )*?
          \n
       |
          (?:
               "
               (?: \\[\S\s] | [^"\\] )*
               "
            |  '
               (?: \\[\S\s] | [^'\\] )*
               '
            |  [^\/"'\\]*
          )
     )+
1    (
          \/\* [^*]* \*+
          (?: [^\/*] [^*]* \*+ )*
          \/
1    )
     /


Regex 2:

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

     /
1    (
          \/\* [^*]* \*+
          (?: [^\/*] [^*]* \*+ )*
          \/
1    )
  |
2    (
          \/\/
          (?: [^\\] | \\\n? )*?
2    )
     \n
  |
     (?:
          "
          (?: \\[\S\s] | [^"\\] )*
          "
       |  '
          (?: \\[\S\s] | [^'\\] )*
          '
       |  [\S\s][^\/"'\\]*
     )
     /g
于 2012-06-21T22:50:14.140 回答