2017-05-07 52 views
2

我的例子是用貪婪工作,當我用來捕獲一個字符串和一個組的整個值(在組[1]中)與一對單引號未能從正則表達式組獲得特定文本

但是,當我想捕捉的字符串的整個值和一組(在組[1] ONLY)與多對單引號的封裝,它只能捕獲字符串的值與最後一對包圍但不是第一個和最後一個單引號之間的字符串。

  string val1 = "Content:abc'23'asad";   
      string val2 = "Content:'Scale['#13212']'ta"; 

      Match match1 = Regex.Match(val1, @".*'(.*)'.*"); 
      Match match2 = Regex.Match(val2, @".*'(.*)'.*"); 
      if (match1.Success) 
      { 
       string value1 = match1.Value; 
       string GroupValue1 = match1.Groups[1].Value; 
       Console.WriteLine(value1); 
       Console.WriteLine(GroupValue1); 

       string value2 = match2.Value; 
       string GroupValue2 = match2.Groups[1].Value; 
       Console.WriteLine(value2); 
       Console.WriteLine(GroupValue2); 

       Console.ReadLine(); 

       // using greedy For val1 i am getting perfect value for- 
       // value1--->Content:abc'23'asad 
       // GroupValue1--->23 

       // BUT using greedy For val2 i am getting the string elcosed by last single quote- 
       // value2--->Content:'Scale['#13212']'ta 
       // GroupValue2---> ] 
       // But i want GroupValue2--->Scale['#13212'] 
      } 
+0

儘管在Regex中有這種嵌套的東西在技術上是可行的,但它聽起來像你實際需要的是解析器。 – Abion47

+0

如果你需要用正則表達式或任何解析器來解決它,你需要定義'''被認爲是分隔符的位置,以及部分子串匹配的位置。否則,沒有解決方案。爲什麼你知道'Scale ['#13212']'應該在組1中?此外,請嘗試'[^'] *'((?:'[^'] *'| [^'])*)'。*' –

+1

這太貪心了.. [''(。*)''] (https://regex101.com/r/ZkuERX/1) – Slai

回答

0

首先使用命名匹配的捕捉組如(?<Data> ...)那麼你可以通過它的名稱來訪問該組中的C#如match1.Groups["Data"].Value


其次,儘量不要使用*這意味着從零到很多。是否真的會有沒有數據?對於大多數情況,答案是否定的,有數據。使用,一對多來代替。

恕我直言*擰了更多的模式,因爲它必須找到零數據,當它這樣做時,它跳過不合理的數據量。當你知道有數據使用+


這是更好地匹配什麼是已知的,未知的比,我們會創造什麼是的模式。同樣在該燈中,使用否定集[^ ]來捕獲文本,如[^']+,其說明捕獲一切爲而非a,一次到多次。

模式

Content:\x27?[^\x27?]+\x27(?<Data>[^\27]+?)\x27 

結果在你的兩組數據是23#13212並放置到比賽捕捉group[1]group["Data"]

注意\x27是單引號'的十六進制轉義。 \x22是用於雙引號",我敢打賭是你真正遇到的。

我在處理引號時使用了十六進制轉義符,因此不必與C#編譯器混淆,認爲它們在解析時引號。

+0

[您的模式與整個內容字符串不匹配。](https://regex101.com/r/kWTDIR/1) – Abion47

+0

@ Abion47我同意100%。因爲由於匹配捕獲要求('...')',用戶只關注(內部)一對''之間的文本,所以我將模式集中在那個上面。除非OP返回並說,否則我需要'match.groups [0]'以及'match.groups [1]',我會堅持這個答案。 – OmegaMan

+0

OP不僅僅關注內部撇號內的文本。看起來他想要這些撇號。在OP的問題中的代碼的評論中,他說他希望'Scale ['#13212']'作爲輸出。你的模式將關閉方括號,它告訴我它不會檢索外部撇號內字符串的全部內容。 – Abion47

1

你現有的正則表達式的問題是你使用了太多的貪婪修飾符。第一個將抓住一切,直到它進入字符串中倒數第二個撇號。這就是爲什麼第二個例子的最終結果只是最後一對引號內的內容。

有幾種方法可以解決這個問題。最簡單的方法是使用SLAI的建議 - 只是一個模式,以最「開」可用單引號內搶什麼,一切:

'(.*)' 

一個更加明確的方法是略微調整當前正在使用的模式。只要改變第一貪修改成一個懶惰的一個:

.*?'(.*)'.* 

或者,你可以改變點在第一和最後一節其他每個字符的撇號,而不是匹配比

[^']*'(.*)'[^']* 

你最終選擇哪一個取決於你個人的追求。但有一點需要注意的是,根據Regex101,第一個選項涉及最少的步驟,所以它將是最有效的方法。但是,它也會丟棄字符串的其餘部分,但我不知道這對您是否重要。