C# 使用正则表达式删除注释

C# 使用正则表达式删除注释,c#,regex,C#,Regex,我正在构建一个解析器,我想从不同的行中删除注释。比如说, variable = "some//thing" ////actual comment 注释标记是/。在这种情况下,变量将包含“some//thing”,其他所有内容都将被忽略。我计划用正则表达式替换它。目前我正在使用(“*”[t])*(\/\/.*)作为正则表达式。然而,替换它将完全替换“一些//东西”////实际注释 我想不出应该用哪个正则表达式来代替。谢谢你的帮助 其他信息-我正在将C#与netcoreapp 1.1.0一起使用

我正在构建一个解析器,我想从不同的行中删除注释。比如说,

variable = "some//thing" ////actual comment
注释标记是
/
。在这种情况下,
变量
将包含
“some//thing”
,其他所有内容都将被忽略。我计划用正则表达式替换它。目前我正在使用
(“*”[t])*(\/\/.*)
作为正则表达式。然而,替换它将完全替换
“一些//东西”////实际注释

我想不出应该用哪个正则表达式来代替。谢谢你的帮助

其他信息-我正在将C#与netcoreapp 1.1.0一起使用

编辑-某些情况下,行可能只包含注释,如
//line comment
。字符串也可能包含转义引号。

旗帜:全球

匹配完整字符串或注释

第一组:评论


因此,如果没有注释,则替换为相同的匹配文本。否则,请在注释本身上执行您的操作。

下面是丑陋的正则表达式模式。我相信它会很好地工作。我用我能想到的每一个病态的例子都试过了,包括包含语法错误的行。例如,一个引号过多或过少的带引号字符串,或者有一个双转义引号,因此不转义。在评论中使用带引号的字符串,当我想提醒自己其他选择时,我会这样做

唯一一次它会出错的情况是,在一个看似带引号的字符串中有一个双斜杠,但不知何故该字符串的格式不正确,并且双斜杠在正确引用的部分之外合法结束。从语法上说,这使它成为一个有效的注释,即使不是程序员的意图。因此,从程序员的角度来看,这是错误的,但根据规则,这实际上是一个注释。也就是说,这种模式似乎只会出错

使用时,模式将返回行的非注释部分。模式中有一个换行符
\n
,允许将其应用于整个文件。如果系统以某种其他方式解释换行符,例如
\r
\r\n
,则可能需要修改该选项。若要在单线模式下使用它,您可以选择将其删除。在一行中为17和18个字符,在多行版本中为第五行、第六行和第七行打印字符。但是,您可以安全地将其保留在那里,因为在单行模式下,它没有任何区别,而在多行模式下,它将为空白的代码行返回一个换行符,或者在第一列中有一个注释开始。如果将结果写入新文件,则原始版本和点画版本中的行号将保持相同。使比较容易

此模式的一个主要警告:它使用的分组结构在正则表达式引擎中具有不同的支持级别。我相信在这里使用时,环顾四周,只有.NET和PCRE引擎才会接受它。它是三级类型:
(?(_条件_uu)然后124; u其他u)
\u条件
模式被视为零宽度断言。如果模式匹配,则在尝试的匹配中使用
\u then
模式,否则使用
\u else
模式。如果没有这种结构,这种模式会发展到不寻常的长度,并且在我的一些病理测试案例中仍然失败

这里呈现的模式与正则表达式引擎需要看到的模式相同。我不是C#程序员,所以我不知道转义引号字符串的所有细微差别。在代码中加入此模式,以便正则表达式引擎能够正确地看到所有反斜杠和引号,这仍然取决于您。也许C#具有与Perl的
herdoc
语法相当的语法

这是要使用的一行模式:

^((?:(?:(?:[^"'/\n]|/(?!/))*)(?("(?=(?:\\\\|\\"|[^"])*"))(?:"(?:\\\\|\\"|[^"])*")|(?('(?=(?:\\\\|\\'|[^'])*'))(?:'(?:\\\\|\\'|[^'])*')|(?(/)|.))))*)
如果要使用“忽略模式空白”选项,可以使用以下版本:

(?x) # Turn on the ignore white space option
^( # Start the only capturing group
    (?: # A non-capturing group to allow for repeating the logic
        (?: # Capture either of the two options below
            [^"'/\n] # Capture everything not a single quote, double quote, a slash, or a newline
            | # OR
            /(?!/) # Capture a slash not followed by a slash [slash an negative look-ahead slash]
        )* # As many times as possible, even if none
        (?(" # Start a conditional match for double-quoted strings
                (?=(?:\\\\|\\"|[^"])*") # Followed by a properly closed double-quoted string
            ) # Then
            (?:"(?:\\\\|\\"|[^"])*") # Capture the whole double-quoted string
            | # Otherwise
            (?(' # Start a conditional match for single-quoted strings
                (?=(?:\\\\|\\'|[^'])*') # Followed by a properly closed single-quoted string
                ) # Then
                (?:'(?:\\\\|\\'|[^'])*') # Capture the whole double-quoted string
                | # Otherwise
                (?([^/]) # If next character is not a slash
                .) # Capture that character, it is either a single quote, or a double quote not part of a properly closed
            ) # end the conditional match for single-quoted strings
        ) # End the conditional match for double-quoted strings
    )* # Close the repeating non-capturing group, capturing as many times as possible, even if none
) # Close the only capturing group
这允许您的代码解释这个怪物,这样当其他人看到它时,或者在几个月后您必须自己处理它时,就没有WTF时刻了。我认为这些评论很好地解释了这一点,但请随意改变它们

如上所述,条件匹配分组的支持有限。它将失败的一个地方是你在之前的评论中链接到的网站。因为您使用的是C#,所以我选择在中进行测试,它可以处理这些构造。它还包括一个很好的参考。如果侧边有正确的选择,您可以测试上面的任何一个版本,并对其进行实验。考虑到它的复杂性,我建议您在某个地方,根据您的文件中的数据,以及您可以想象的任何边缘案例和病理测试来测试它


为了弥补这个小模式的不足,有一个更大的模式用于测试电子邮件地址,它是78列81行,还有几十个字符可供使用。(我不建议使用它或任何其他正则表达式来测试电子邮件地址。这是一个错误的工具。)如果你想吓唬自己,可以在网站上浏览一下。我和那件事无关

您是在分析现有语言,还是这是一种自定义格式?它是一种自定义语言<代码>“[^”]*”(//.*)
,但这不包括转义引号-
“some\”//thing”
,例如。字符串也可能包含转义引号。我会尽量利用这个链接。@KenY-N我想出了这个
“(?>[^\\\N”“]+\\\)*”(\/\/.*)
。虽然这会处理转义引号,但让我们看看是否有人能想出更健壮的东西。与之相比,它如何?哪一个更好?谢谢你的努力,但是你的正则表达式没有把注释和引号分开,比如
“qwe\”qwe“\\asd
。现在我用
”(?>[^\\\\n]+\\\\)*“|(\/\/.*)
()。我还查看了链接。那个正则表达式是个怪物。再次感谢您的努力!我的错误。我用反斜杠而不是正斜杠。您的解决方案非常有效!而且它还帮我省去了分离条纹的头痛