2011-07-09 126 views
3

我试图解析以下行:C#正则表达式表达问题

"\#" TEST #comment hello world 

在我输入时,#COMMENT总是在该行的末尾。有可能没有评论,但如果有的话,它总是在行的末尾。

我用下面的正则表达式解析它:

(\#.+)? 

我有RegexOption.RightToLeft上。我预计它拉#comment hello world。但相反,它正在拉"#" TEST #comment hello world"

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

+0

你必须解析整个字符串,字符转义和所有...仅供参考,它比它看起来更难**。 – Mehrdad

+0

想象一下''\#“测试#”测试#评论hello world“ - 大概是从第二个'#'开始的评论 - 但你怎么区分? –

+0

@Damien - 评论开始于第三个#实际上。区分它的方法是评论总是在最后,因此从右到左解析它直到碰到第一个#是我的目标 – Icemanind

回答

0

我觉得想拉这个时候你会发现too many edge cases用正则表达式关闭。处理报价是真正使事情复杂化的原因,更不用说转义字符了。

程序性解决方案并不复杂,并且根据需要更快更容易修改。请注意,我不知道转义字符应该是在你的榜样是什么,但你肯定会添加到算法...

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 

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

0

+运算符试图尽可能多地匹配它。为了尽可能少的时间匹配越好,使用它的懒惰当量,+?

(#.+?) 

。当然,这会带来麻烦地用含有#评论:

"\#" TEST #comment #hello #world 
+2

你测试过了吗? –

+0

不幸的是,你永远不会有像'#####重要的线#####' – Howard

+0

@Steve Wortham:是的,它的工作。正如问题所示,不要忘记打开RightToLeft选项。 – Andomar

1

重要的问题是:你如何看到行尾的#和开始注释的#之间的区别?为了简单起见,我们假设最后#开始评论。

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

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

所以让我们把它放到一个正则表达式中:#[^#]*$。你不需要RightToLeft。据我所知,你也不需要在C#正则表达式中转义#。当然,如果您提供有关如何查看“有效”#和“注释开始”#之间差异的信息,则可以找到更优雅的解决方案,允许#以内的评论。

+0

整个问题就是'#'开始混乱了 – Mehrdad

+0

@Mehrdad:谢谢,我误解了,我会修复它 – Heinzi

+0

@Mehrdad:修正 – Heinzi

0

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

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

为你提供了测试字符串,这个正则表达式正确拉动评论(右至左选项):/((?: #).+)$/

免责声明:

  • 也拉空白刚'#'之前 ,所以你可能需要做一个 修剪。
  • 评论不能包含在其中的顺序“#”
0

这之后它匹配“#”和一切,女巫是预期的行为:)

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

希望这有助于

0

对,我测试过这个,它似乎是必要的。

\#.+(\#.+)$ 

具体来说,它跳过过去的第一#,然后捕获一切​​从第二#到该行的结束,返回

#comment hello world