2016-09-20 113 views
1

這裏是有問題的字符串的示例:C#字符串處理非分隔字符串列出

[952,M] [782,M] [782] {2[373,M]} [1470] [352] [235] [234] {3[610]}{3[380]} [128] [127] 

我已經加入了空格,但它確實沒有幫助擊穿。我想要做的是將方括號中的每個「字段」添加到字符串列表中。我可以處理的下一個問題是一些字段也有一個逗號分隔的部分,我可以在事後分離。真正的問題在於花括號。例如{2[373,M]}方括號外的數字是方括號的重複。

對於我的生活,我無法找到一種方法,我可以一直將該行分割成一個字符串列表。

準代碼如下:

for(i = 0 to string.length) 
{ 
    if string.substring(i,1) = "]" 
     int start1 = i 
    elseif string.substring(i,1)="[" 
     int start1 = i 
    elseif string.substring(i,1) = "{" 
     int start2 = i 
    elseif string.substring(i,1) = "}" 
     int end2 = i 
} 

我想過使用代碼的想法上面串出每一個「場」,但在大括號中還含有方括號。任何想法將不勝感激。

+1

是在'{3 [610]} {3 [380]}'一個錯字或東西,你可以在預期缺乏空間的你輸入? –

+0

1)你想要什麼* {{2 [373,M]}'變成?兩串'373,M'? 2)'string.substring(i,1)==「]」'是荒謬的。只要'string [i] ==']''。 – itsme86

+0

Asad Saeeduddin這是我的字符串操作錯誤。 – jhdeval

回答

1
var s = "[952,M] [782,M] [782] {2[373,M]} [1470] [352] [235] [234] {3[610]}{3[380]} [128] [127]"; 

var s2 = Regex.Replace(s, @"\{(\d+)(\[[^]]+\])\}", m => string.Concat( 
    Enumerable.Repeat(m.Groups[2].Value, int.Parse(m.Groups[1].Value)))); 

var a = s2.Split("[] ".ToArray(), StringSplitOptions.RemoveEmptyEntries); 

// s2 = "[952,M] [782,M] [782] [373,M][373,M] [1470] [352] [235] [234] [610][610][610][380][380][380] [128] [127]" 
// a = {"952,M","782,M","782","373,M","373,M","1470","352","235","234","610","610","610","380","380","380","128","127"} 
0

你可以使用正則表達式。

編輯:這個管理問題,逗號和repetititon:

 var regex3 = new Regex(@"(\B\[([a-zA-Z0-9\,]+)\])|(\{(\d+)\[([a-zA-Z0-9\,]+)\]\})"); 
     var stringOne = "[952,M] [782,M] [782] {2[373,M]} [1470] [352] [235] [234] {3[610]}{3[380]} [128] [127]"; 
     var matches = regex.Matches(stringOne); 

     var listStrings = new List<string>(); 

     foreach (Match match in matches) 
     { 
      var repetitor = 1; 
      string value = null; 
      if (match.Groups[1].Value == string.Empty) 
      { 
       repetitor = int.Parse(match.Groups[4].Value); 
       value = match.Groups[5].Value; 
      } 

      else 
      { 
       value = match.Groups[2].Value; 
      } 

      var values = value.Split(','); 
      for (var i = 0; i < repetitor; i++) 
      { 
       listStrings.AddRange(values); 
      } 
     } 
+0

這是死的關閉它唯一的問題是它是大括號。方括號外的數字表示重複。這個{3 [610]}將被添加到列表中3次。 – jhdeval

1

如果我理解正確的話,你想拆用方括號括字符,當他們有大括號重複指定號碼裏面的內容的時代。

您可以提取您需要使用正則表達式的所有信息,包括你需要重複支架

var input = @"[952,M] [782,M] [782] {2[373,M]} 
       [1470] [352] [235] [234] {3[610]}{3[380]} [128] [127]"; 

var pattern = @"((:?\{(\d+)(.*?)\})|(:?\[.*?\]))"; 

MatchCollection matches = Regex.Matches(input, pattern); 

var ls = new List<string>(); 

foreach(Match match in matches) 
{ 
    // check if the item has curly brackets 
    // The captures groups will be different if there were curly brackets 

    // If there are brackets than the 4th capture group 
    // will have the value of the square brackets and it's content 
    if(match.Groups[4].Success) 
    { 
     var value = match.Groups[4].Value; 

     // The "Count" of the items will 
     // be in the third capture group 
     var count = int.Parse(match.Groups[3].Value); 

     for(int i=0;i<count;i++) 
     { 
      ls.Add(value); 
     } 

    } 
    else 
    { 
     // otherwise we know that square bracket input 
     // is in the first capture group 
     ls.Add(match.Groups[1].Value); 
    } 
} 

這裏確定的次數所需要的數量是解決方案的工作小提琴:https://dotnetfiddle.net/4rQsDj

這裏是輸出:

[952,M] 
[782,M] 
[782] 
[373,M] 
[373,M] 
[1470] 
[352] 
[235] 
[234] 
[610] 
[610] 
[610] 
[380] 
[380] 
[380] 
[128] 
[127] 

如果你不想支架可通過改變正則表達式模式以擺脫他們和match.Groups[1].Valuematch.Groups[6].Value

這裏是方括號工作的解決方案:https://dotnetfiddle.net/OQwStf

+0

這似乎是最好的RegEx解決方案。與我的解決方案相比,我會對性能感到好奇。 –

+0

@JonathanWood不知道,知道肯定有很大的字符串正則表現的問題,也許我會弄亂小提琴看看我是否注意到任何東西 – konkked

+0

在1K行文本,花了大約.08s,並在500採取.03秒,因此看起來像是線性增長,如果實現者編譯它可能會提高性能 – konkked

1

正則表達式下面將處理這兩種情況下:

(?:\{([^\[]+)){0,1}\[([^\]]+)\]\}{0,1} 

對於沒有花括號爲您的情況下比賽,第一場比賽將是空的。對於第二種情況,第一場比賽將包含您的重複次數。在這兩種情況下,第二場比賽將包含實際數據。下面的鏈接將顯示此工作的一個演示:

Regex Demo

但是請注意,你將不得不自己處理的重複中,使得使用正則表達式

1

,而你可能能夠代碼如果你的需求變得太複雜,它可能會縮短。所以下面的代碼顯示了我將採取的一般方法來實現這一點。它有點快而骯髒,但符合你的要求。

此外,我有一個parsing helper class,這將使這個代碼更容易編寫和更健壯。

string input = "[952,M] [782,M] [782] {2[373,M]} [1470] [352] [235] [234] {3[610]}{3[380]} [128] [127]"; 
int pos = 0; 

void Main() 
{ 
    while (pos < input.Length) 
    { 
     SkipWhitespace(); 
     if (pos < input.Length && input[pos] == '{') 
      ParseBrace(); 
     else if (pos < input.Length && input[pos] == '[') 
      ParseBracket(); 
    } 
} 

void SkipWhitespace() 
{ 
    while (pos < input.Length && char.IsWhiteSpace(input[pos])) 
     pos++; 
} 

void ParseBrace() 
{ 
    Debug.Assert(pos < input.Length && input[pos] == '{'); 
    int pos2 = input.IndexOf('[', pos + 1); 
    if (pos2 < 0) 
     pos2 = input.Length; 

    int count = int.Parse(input.Substring(pos + 1, pos2 - pos - 1)); 
    for (int i = 0; i < count; i++) 
    { 
     pos = pos2; 
     ParseBracket(); 
    } 

    pos2 = input.IndexOf('}', pos2 + 1); 
    if (pos2 < 0) 
     pos2 = input.Length; 

    pos = pos2 + 1; 
} 

void ParseBracket() 
{ 
    Debug.Assert(pos < input.Length && input[pos] == '['); 
    int pos2 = input.IndexOf(']', pos + 1); 
    if (pos2 < 0) 
     pos2 = input.Length; 
    Console.WriteLine(input.Substring(pos + 1, pos2 - pos - 1)); 
    pos = pos2 + 1; 
} 

輸出示例:

952,M 
782,M 
782 
373,M 
373,M 
1470 
352 
235 
234 
610 
610 
610 
380 
380 
380 
128 
127