我正在尝试编写一个正则表达式(在 JavaScript 中),它将匹配 JS 文件开头的多行注释。
到目前为止,我想出了这个:/^(\/\*[^\*\/]*\*\/)/g
它适用于单行注释:http
://refiddle.com/24o
但我的问题是它不适用于多行注释:http ://refiddle.com/24m
您有任何解决方法的想法吗?
我正在尝试编写一个正则表达式(在 JavaScript 中),它将匹配 JS 文件开头的多行注释。
到目前为止,我想出了这个:/^(\/\*[^\*\/]*\*\/)/g
它适用于单行注释:http
://refiddle.com/24o
但我的问题是它不适用于多行注释:http ://refiddle.com/24m
您有任何解决方法的想法吗?
像HTML一样,JavaScript不能被正则表达式解析。试图正确地这样做是徒劳的。
相反,您必须使用将 JavaScript 源代码正确转换为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 并提取您需要的内容即可。
您建议的正则表达式不起作用,因为*
评论中有 a 。此外,它只会查找文件开头的注释。
尝试改用这个:
/\/\*[\s\S]*?\*\//
这是一个匹配任何多行或单行注释的注释:
/(\/\*.*?\*\/|\/\/[^\n]+)/
如果您只想要多行匹配,请放弃后半部分:
/\/\*.*?\*\//
对于这两个,请确保您s
设置了标志,以便.
匹配新行。
我不是 javascript 专家,但似乎必须考虑 C/C++ 注释。
正确完成意味着必须在过程中考虑报价(转义和所有这些)。
以下是两种有效的正则表达式方法。Regex 1 直接找到第一个C风格的注释,一匹配就找到了。正则表达式 2 是一般情况。它查找 C 样式、C++ 样式或非注释,是全局的,并允许您在找到所需内容时中断。
代码
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