正则表达式到源代码注释
Posted
技术标签:
【中文标题】正则表达式到源代码注释【英文标题】:Regex to source code comments 【发布时间】:2015-02-16 11:59:57 【问题描述】:是否有正则表达式来匹配任何行注释,但避免字符串中的 cmets?
我需要//
之后的一行中的所有内容(包括//
)
例如:
//Comment (match!)
bla bla bla bla //Comment (match!)
this string "foo // foo" (don't match because it's inside "")
【问题讨论】:
我不认为你可以做这个纯正则表达式 你可以,正如我的回答所展示的那样。我原本打算证明语法是context-free 而不是regular,但我最终创建了a finite automation,它可以识别语法。 【参考方案1】:以下regular expression 将正确匹配输入中的任何字符串和正则表达式:
var strings = /("((.|\\\n)*?([^\\"]|\\\\)|)"|'((.|\\\n)*?([^\\']|\\\\)|)'|\/[^*](.*([^\\\/]|\\\\))\/|\/\*\/)/g;
您可以从输入中删除字符串,然后使用 another regular expression 匹配 cmets:
var comments = /((\/\/)(.*)|(\/\*)((.|\n)*)(\*\/))/g;
input.replace(strings, "").match(comments);
var strings = /("((.|\\\n)*?([^\\"]|\\\\)|)"|'((.|\\\n)*?([^\\']|\\\\)|)'|\/[^*](.*([^\\\/]|\\\\))\/|\/\*\/)/g,
comments = /((\/\/)(.*)|(\/\*)((.|\n)*)(\*\/))/g;
function update()
var arr = input.value.replace(strings, "").match(comments);
output.value = arr ? arr.join("\n") : "";
input.onkeydown = input.onkeyup = input.onchange = update;
update();
textarea
width: 90%;
height: 5em;
<p>Input:</p>
<textarea id="input">
//Comment (match!)
bla bla bla bla //Comment (match!)
this string "foo // foo"
</textarea>
<p>Output:</p>
<textarea id="output">
</textarea>
【讨论】:
给出误报,考虑: a + "//" + b 【参考方案2】:此正则表达式适用于所有情况(请参阅regex101 example):
(("[^"]*)2)*(\/\/.*)
您想要与第三个捕获组匹配的任何内容。或者,您可以将前两组设为非捕获。
它的工作原理是在点击双斜杠之前跳过任何偶数个引号,后跟其他文本。
【讨论】:
然后出现像"\""
这样的字符串并且它停止工作。
你是对的。我添加了另一个解决方案,它以完全不同的方式处理它,并处理所有情况。
@Biffen:这个答案不能处理,但我的 OTHER 答案可以。在 regex101 中尝试一下。【参考方案3】:
^[^"]*(//.*)
不会捕获所有情况,但至少您的示例应该有效
更新:开头缺少^
。
【讨论】:
它不起作用,即使在示例中也是如此。[^"]*
不必匹配任何东西,因为量词,所以任何双斜杠都会匹配。
您可以添加以“”分隔的封闭字符串:^([^"]|\"(\\\"|[^"])*\")*(//.*) 考虑那 \" 可能出现在字符串中【参考方案4】:
这是另一个应该捕获每个单行注释的解决方案(请参阅它在 regex101 上的工作):
(\/\/.*)|"(?:\\"|.)*?"
所有的cmet都将被捕获在第一个匹配组中。
它适用于任何具有惰性量词的正则表达式风格,几乎是所有这些。我使用的技术是专门匹配带引号的字符串,以便它们从可用的文本中“删除”以匹配我们想要的内容:cmets。这种技术在 RexEgg.com 上详细解释为The Greatest Regex Trick Ever。
细分:
(\/\/.*)
匹配 cmets,并在组中捕获
"(?:\\"|.)*?"
匹配带引号的字符串,避免其中的任何转义引号
(?:\\"|.)
匹配转义引号或下一个字符,成功地直接传递转义引号,而不是让它们匹配为“真实”引号
整个交替都有 *?
惰性量词,因此它会命中下一个“真实”引号,而不是继续到另一个带引号的字符串。
【讨论】:
以上是关于正则表达式到源代码注释的主要内容,如果未能解决你的问题,请参考以下文章