正则表达式到源代码注释

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,并在组中捕获

"(?:\\"|.)*?" 匹配带引号的字符串,避免其中的任何转义引号

内部非捕获组 (?:\\"|.) 匹配转义引号或下一个字符,成功地直接传递转义引号,而不是让它们匹配为“真实”引号 整个交替都有 *? 惰性量词,因此它会命中下一个“真实”引号,而不是继续到另一个带引号的字符串。

【讨论】:

以上是关于正则表达式到源代码注释的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式在代码中查找空注释

Python 3 正则表达式查找多行注释

正则表达式匹配代码中的特定注释

正则表达式检测代码中的注释[重复]

javascript 正则表达式在代码中查找注释

防止在正则表达式上回溯以查找非注释行(不以缩进的“#”开头)