注意,这里的目标不是词法分析,所以请不要建议lexing或解析代码。而且,我为加入“正则表达式”评论的混乱而道歉。问题,但最好的(投票最多)bad answer(根据问题如何使用结果的背景)是不够的(虽然我能够从那里开始)和许多其他答案我&# 39;经过审查与我试图做的事情无关。
我已经构建了一个原则上正常工作的正则表达式here。
/(?:\n|^)(?:[^'"])*?(?:'(?:[^\\\r\n]|[\\]{2}|\\')*'|"(?:[^\\\r\n]|[\\]{2}|\\")*")*?(?:[^'"])*?(\/\*(?:[\s\S]*?)\*\/)/g
最后一组很好地匹配了块注释,作为上述SO中的参考:
(\/\*(?:[\s\S]*?)\*\/)
实际匹配之前的所有内容都将被丢弃,但用于匹配有效的块注释 - 即不是在字符串文字中找到的内容。
忽略正则表达式看起来像块注释的情况。
假设输入字符串是linted,而不是自由形式的javascript。
但in practice,我在第一场比赛中获得了重复,而没有其他比赛。
为什么呢?如何纠正在实践中工作?
提前感谢您的帮助和任何问题,这个问题可能会帮助您解决问题。 :)
另外(在评论部分),鉴于以下信息,欢迎任何潜在的陷阱。
与直接问题无关的额外信息: 正如示例代码中所暗示的,最终目标是以这种方式替换/折叠任何嵌套或其他代码结构,以便专注于给定代码补丁的词法范围顶部的变量声明 - 对于提升变量声明的目的,为特定用例生成模板。我知道这听起来像是一个负载,但我相信这是可能的,并且相对直接 - 不完全简单的替换 - 但也是如此。为了参考我的意思"可能",我宁愿只折叠正则表达式,阻止注释和内联注释EDIT:和字符串文字/ EDIT,然后在{中递归地仅折叠变量范围(或普通对象) blocks}(所有这些都不包含任何嵌套的块)直到它们消失,然后看看剩下的是什么。如果它因任何原因而无法正常工作,请仅在评论中回复。谢谢!
答案 0 :(得分:1)
这是其中之一“呃,是的,当然!”时刻。
exec()
函数将生成一个包含1个元素的数组,作为匹配元素。除非没有,否则第一个元素是完全匹配,除非有捕获组,否则非常好。如果有,则除result[0]
为完整模式匹配外,result[1]
将是第一个捕获组,result[2]
是第二个捕获组,依此类推。
例如:
(/l/g).exec("l")
向我们提供["l"]
(/(l)/g).exec("l")
向我们提供["l", "l"]
你的问题不是问题(尽管通过流过滤器运行字符串来取出块注释可能更容易使用),因为它更多的是假设你可以使用{{1} } .join()
结果导致你出现问题。如果您有捕获组,并且有结果,请加入exec
,或在加入前删除前导元素之前调用results.slice(1)
,这样您就不会意外地包含完整匹配。
答案 1 :(得分:-1)
评论解析:下面有两个版本。一个保留格式,一个没有格式的。
在两者中,您必须检查捕获组。第1组是评论 第2组是非评论。
这是相关的,例如,如果您要更换(或删除)评论 或不评论。
这不会保留格式:
# raw: (/\*[^*]*\*+(?:[^/*][^*]*\*+)*/|//(?:[^\\]|\\\n?)*?\n)|("(?:\\[\S\s]|[^"\\])*"|'(?:\\[\S\s]|[^'\\])*'|[\S\s][^/"'\\]*)
# delimited: /(\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\/|\/\/(?:[^\\]|\\\n?)*?\n)|("(?:\\[\S\s]|[^"\\])*"|'(?:\\[\S\s]|[^'\\])*'|[\S\s][^\/"'\\]*)/
( # (1 start), Comments
/\* # Start /* .. */ comment
[^*]* \*+
(?: [^/*] [^*]* \*+ )*
/ # End /* .. */ comment
|
// # Start // comment
(?: [^\\] | \\ \n? )*? # Possible line-continuation
\n # End // comment
) # (1 end)
|
( # (2 start), Non - comments
"
(?: \\ [\S\s] | [^"\\] )* # Double quoted text
"
| '
(?: \\ [\S\s] | [^'\\] )* # Single quoted text
'
| [\S\s] # Any other char
[^/"'\\]* # Chars which doesn't start a comment, string, escape,
# or line continuation (escape + newline)
) # (2 end)
这样做(注意 - 如果\h
水平制表符构造导致问题,请改用[^\S\r\n]
):
# raw: ((?:(?:^\h*)?(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/(?:\h*\n(?=\h*(?:\n|/\*|//)))?|//(?:[^\\]|\\\n?)*?(?:\n(?=\h*(?:\n|/\*|//))|(?=\n))))+)|("(?:\\[\S\s]|[^"\\])*"|'(?:\\[\S\s]|[^'\\])*'|[\S\s][^/"'\\\s]*)
# delimited: /((?:(?:^\h*)?(?:\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\/(?:\h*\n(?=\h*(?:\n|\/\*|\/\/)))?|\/\/(?:[^\\]|\\\n?)*?(?:\n(?=\h*(?:\n|\/\*|\/\/))|(?=\n))))+)|("(?:\\[\S\s]|[^"\\])*"|'(?:\\[\S\s]|[^'\\])*'|[\S\s][^\/"'\\\s]*)/
( # (1 start), Comments
(?:
(?: ^ \h* )? # <- To preserve formatting
(?:
/\* # Start /* .. */ comment
[^*]* \*+
(?: [^/*] [^*]* \*+ )*
/ # End /* .. */ comment
(?: # <- To preserve formatting
\h* \n
(?=
\h*
(?: \n | /\* | // )
)
)?
|
// # Start // comment
(?: [^\\] | \\ \n? )*? # Possible line-continuation
(?: # End // comment
\n
(?= # <- To preserve formatting
\h*
(?: \n | /\* | // )
)
| (?= \n )
)
)
)+ # Grab multiple comment blocks if need be
) # (1 end)
| ## OR
( # (2 start), Non - comments
"
(?: \\ [\S\s] | [^"\\] )* # Double quoted text
"
| '
(?: \\ [\S\s] | [^'\\] )* # Single quoted text
'
| [\S\s] # Any other char
[^/"'\\\s]* # Chars which doesn't start a comment, string, escape,
# or line continuation (escape + newline)
) # (2 end)