C#正则表达式问题

我试图解析以下行:

"\#" TEST #comment hello world 

在我的输入中,#comment始终位于该行的末尾。 可能有也可能没有评论,但如果有,它总是在行的末尾。

我使用以下正则表达式来解析它:

 (\#.+)? 

我有RegexOption.RightToLeft 。 我期待它能够拉动#comment hello world 。 但相反,它正在拉"#" TEST #comment hello world"

为什么我的Regex表达式没有拉出正确的东西,什么是我需要使其正确拉动的有效Regex表达式?

我认为你试图用正则表达式来解决这个问题会发现太多边缘情况 。 处理引号确实使事情复杂化,更不用说转义字符了。

程序解决方案并不复杂,并且根据需要更快更容易修改。 请注意,我不知道您的示例中的转义字符应该是什么,但您当然可以将其添加到算法中…

 string CodeSnippet = Resource1.CodeSnippet; StringBuilder CleanCodeSnippet = new StringBuilder(); bool InsideQuotes = false; bool InsideComment = false; Console.WriteLine("BEFORE"); Console.WriteLine(CodeSnippet); Console.WriteLine(""); for (int i = 0; i < CodeSnippet.Length; i++) { switch(CodeSnippet[i]) { case '"' : if (!InsideComment) InsideQuotes = !InsideQuotes; break; case '#' : if (!InsideQuotes) InsideComment = true; break; case '\n' : InsideComment = false; break; } if (!InsideComment) { CleanCodeSnippet.Append(CodeSnippet[i]); } } Console.WriteLine("AFTER"); Console.WriteLine(CleanCodeSnippet.ToString()); Console.WriteLine(""); 

此示例将注释从CodeSnippet 。 我以为那就是你追求的。

这是输出:

 BEFORE "\#" TEST #comment hello world "ab" TEST #comment hello world "ab" TEST #comment "hello world "ab" + "ca" + TEST #comment "\#" TEST "ab" TEST AFTER "\#" TEST "ab" TEST "ab" TEST "ab" + "ca" + TEST "\#" TEST "ab" TEST 

正如我所说,你可能需要在算法中添加转义字符。 但这是一个很好的起点。

重要的问题是:你如何看待行尾的#和开始评论的#之间的区别? 让我们假设为了简单起见,# last开始发表评论。

在这种情况下,你想要匹配的是

  • 一个#
  • 不包含#的任意文本序列
  • 直到行结束

所以我们把它放到一个正则表达式中: #[^#]*$ 。 你不需要RightToLeft。 据我所知,你也不需要在C#正则表达式中转义#

当然,如果您提供有关如何查看“有效”#和“注释开始”#之间区别的信息,则可以找到一个更优雅的解决方案,允许注释中使用#。

+运算符尝试尽可能多地匹配。 要尽可能少地匹配,使用它的懒惰等价物, +?

 (#.+?) 

当然,这会给包含#注释带来麻烦:

 "\#" TEST #comment #hello #world 

使用“#。+”。 我离开了测试,因为#不是公认的转义序列。 我遗漏了(,)和? 因为他们不需要。

 Regex regex = new Regex(" #.+"); Console.WriteLine(regex.Match("#\" TEST #comment hello world")); 

对于你给出的测试字符串,这个正则表达式正确地拉动注释(从右到左选项): /((?: #).+)$/

免责声明:

  • 还要在“#”之前拉出空格,这样您可能需要进行修剪。
  • 注释不能包含序列“#”

这将匹配“#”及其后的所有内容,女巫是预期的行为:)

 var reg = new Regex("#(.)*") 

希望这可以帮助

是的,我已经测试了这个,它似乎做了必要的。

 \#.+(\#.+)$ 

具体来说,它跳过第一个#,然后捕获从第二个#到行尾的所有内容,返回

 #comment hello world