2011-07-09 188 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