2015-04-02 64 views
1

我有以下字符串:如何以特殊順序提取括號內的文本?

Find string inside brackets [C#.net [C# Only] [PHP and SQl [MySQL] ] ] and [Vb.net] examples. 

,我想輸出如下:

1 - [C#.net [C# Only] [PHP and SQl [MySQL] ] ] 
    2 - [C# Only] 
    3 - [PHP and SQl [MySQL] ] 
    4 - [MySQL] 
    5 - [Vb.net] 

我的代碼是:

string regularExpressionPattern = @"\[([^]]*)\]"; 
string text = "Find string inside brackets [C#.net [C# Only] [PHP and SQl [MySQL] ] ] and [Vb.net] examples."; 
Regex re = new Regex(regularExpressionPattern); 
int i = 0 ; 
foreach (Match m in re.Matches(text)) 
{ 
    i++; 
    Console.WriteLine(i + " - " + m.Value); 
} 

和電流(不正確)的輸出:

1 - [C#.net [C# Only] 
2 - [PHP and SQl [MySQL] 
3 - [Vb.net] 

回答

1

你將需要平衡組。 This不是一個確切的重複,但正則表達式可以用來解決您的問題。首先是基本的正則表達式:

\[(?:[^\[\]]|(?<o>\[)|(?<-o>\]))+(?(o)(?!))\] 

\[   # Match an opening square bracket 
(?:   # Group begin 
    [^\[\]]  # Match non-square brackets 
|    # Or 
    (?<o>\[) # An opening square bracket which we name 'o'. 
|    # Or 
    (?<-o>\]) # A closing square bracket and we remove an earlier square bracket 
)+   # Repeat the group as many times as possible 
(?(o)(?!)) # Fail if a group named 'o' exists at this point 
\]   # Match the final closing square bracket 

然後拿到內部匹配,你可以使用一個前瞻和捕獲組這樣你就可以得到重疊的匹配:

(?=(\[(?:[^\[\]]|(?<o>\[)|(?<-o>\]))+(?(o)(?!))\])) 

ideone demo

+0

我忘了提:使用'm.Groups [1] .Value'後來因爲上述正則表達式代碼得到結果第一個捕獲小組。你可以看到我在演示中正好使用了 – Jerry 2015-04-02 07:37:02

+0

我是正規表達式的一週,我可以找到很好的教程我們的示例學習 – Milad 2015-04-02 07:54:08

+1

@Milad你也許可以使用http://www.regular-expressions.info/我個人看那裏,或者在StackOverflow上搜索,因爲機會可能是之前問過的類似問題,或者稍微不同的問題已經解決,我可以在將它適配到我需要的東西后使用該解決方案:) – Jerry 2015-04-02 07:55:57

1

我知道臨時工正則表達式很棒,人們用它們來做各種奇妙的事情。但簡單的事實是,他們是一個痛苦。雖然我確信他們擁有許多優秀的用戶,但傑米·扎文斯基並不是絕對沒有「有些人在面臨問題時認爲」我知道,我會用正則表達式「。現在他們有兩個問題。」報價仍然被引用。

這不是說你需要用槓桿打敗使用正則表達式,但也許只是證明有無限的其他方式?所以我適應了一個普通的,這不是完美的;它不強制括號的配對,它會得到怪物,如果關閉超過開啓支架搞砸了,而且它缺少一些支撐,將使其更具可讀性,但:

static class StringExtensions 
{ 
    private static char open = '['; 
    private static char close = ']'; 
    public static string[] Brackets(this string str) 
    { 
     //Set up vars 
     StringBuilder[] builders = new StringBuilder[str.Count(x => x == open)]; 
     for (int h = 0; h < builders.Count(); h++) 
      builders[h] = new StringBuilder(); 
     string[] results = new string[builders.Count()]; 
     bool[] tracker = new bool[builders.Count()]; 
     int haveOpen = 0; 
     //loop up string 
     for (int i = 0; i < str.Length; i++) 
     { 
      //if opening bracket 
      if (str[i] == open) 
       tracker[haveOpen++] = true; 
      //loop over tracker 
      for (int j = 0; j < tracker.Length; j++) 
       if (tracker[j]) 
        //if in this bracket append to the string 
        builders[j].Append(str[i]); 
      //if closing bracket 
      if (str[i] == close) 
       tracker[Array.FindLastIndex<bool>(tracker, p => p == true)] = false; 
     } 
     for (int i = 0; i < builders.Length; i++) 
      results[i] = builders[i].ToString(); 
     return results; 
    } 
} 

然後你使用它像

foreach (string part in text.Brackets()) 
{ 
    Console.WriteLine(part); 
}