2015-10-31 41 views
0

這是我正在處理的代碼的簡化版本。代碼的目的是獲取一串信息,將其分解並將其解析爲關鍵值對。C#使用正則表達式來分割單詞

使用在下面的示例中的信息,一個字符串可能看起來像:關於上面的例子

"DIVIDE = KE48 CLACOS = 4556D DIV = 3466 INT = 4567" 

還有一點,至少有三個,我們必須分析出偶爾會包括附加價值的功能。這是一個更新的假示例字符串。

"DIVIDE = KE48, KE49, KE50 CLACOS = 4566D DIV = 3466 INT = 4567 & 4568" 

問題在於代碼拒絕分開分割DIVIDE和DIV信息。相反,它會在DIV處繼續分割,然後將其餘的信息分配爲值。

有沒有辦法告訴我的代碼,DIVIDE和DIV需要解析爲兩個單獨的值,並且不要將DIVIDE變成DIV?

public List<string> FeatureFilterStrings 
    { 
     // All possible feature types from the EWSD switch. 
     get 
     { 
      return new List<string>() { "DIVIDE", "DIV", "CLACOS", "INT"}; 
     } 
    } 

public void Parse(string input){ 

    Func<string, bool> queryFilter = delegate(string line) { return FeatureFilterStrings.Any(s => line.Contains(s)); }; 


    Regex regex = new Regex(@"(?=\\bDIVIDE|DIV|CLACOS|INT)"); 
    string[] ms = regex.Split(updatedInput); 
    List<string> queryLines = new List<string>(); 
    // takes the parsed out data and assigns it to the queryLines List<string> 
    foreach (string m in ms) 
    { 
     queryLines.Add(m); 
    } 

    var features = queryLines.Where(queryFilter); 
    foreach (string feature in features) 
     { 
      foreach (Match m in Regex.Matches(workLine, valueExpression)) 
      { 
       string key = m.Groups["key"].Value.Trim(); 
       string value = String.Empty; 

       value = Regex.Replace(m.Groups["value"].Value.Trim(), @"s", String.Empty); 
       AddKeyValue(key, value); 
      } 
     } 

    private void AddKeyValue(string key, string value) 
    { 
     try 
     { 
      // Check if key already exists. If it does, remove the key and add the new key with updated value. 
      // Value information appends to what is already there so no data is lost. 
      if (this.ContainsKey(key)) 
      { 
       this.Remove(key); 
       this.Add(key, value.Split('&')); 
      } 
      else 
      { 
       this.Add(key, value.Split('&')); 
      } 
     } 
     catch (ArgumentException) 
     { 
      // Already added to the dictionary. 
     } 
    }  
} 

的進一步信息,所述字符串信息不具有的每個鍵/值之間的空間的一組數,每個串可以不包括所有的值和特徵不總是以相同的順序。歡迎來解析舊的電話交換機信息。

+0

如何用空格分割輸入的字符串,刪除空項,然後通過字符串數組迭代?正則表達式並不總是最好的選擇 –

回答

1

這可能是你一個簡單的選擇。

試試這個代碼:

var input = "DIVIDE = KE48 CLACOS = 4556D DIV = 3466 INT = 4567"; 

var parts = input.Split(new [] { '=', ' ' }, StringSplitOptions.RemoveEmptyEntries); 

var dictionary = 
    parts.Select((x, n) => new { x, n }) 
     .GroupBy(xn => xn.n/2, xn => xn.x) 
     .Select(xs => xs.ToArray()) 
     .ToDictionary(xs => xs[0], xs => xs[1]); 

然後我得到以下詞典:

dictionary


基於更新後的輸入,事情變得更加複雜,但這個工程:

var input = "DIVIDE = KE48, KE49, KE50 CLACOS = 4566D DIV = 3466 INT = 4567 & 4568"; 

Func<string, char, string> tighten = 
    (i, c) => String.Join(c.ToString(), i.Split(c).Select(x => x.Trim())); 

var parts = 
    tighten(tighten(input, '&'), ',') 
    .Split(new[] { '=', ' ' }, StringSplitOptions.RemoveEmptyEntries); 

var dictionary = 
    parts 
     .Select((x, n) => new { x, n }) 
     .GroupBy(xn => xn.n/2, xn => xn.x) 
     .Select(xs => xs.ToArray()) 
     .ToDictionary(
      xs => xs[0], 
      xs => xs 
       .Skip(1) 
       .SelectMany(x => x.Split(',')) 
       .SelectMany(x => x.Split('&')) 
       .ToArray()); 

我得到這本字典:

dictionary2

+0

這樣的情況下,如果DIVIDE = KE48,KE49,KE60 CLACOS = 4556D DIV = 3466 INT = 4567,4599 – Bryan

+0

@jason - 否,這種情況仍然有效。否。這是否意味着您的輸入格式可能不同從你的問題中的例子?如果是這樣,它有什麼不同? – Enigmativity

+0

是的,對不起,我會上去編輯這個問題。我有我的原始草稿中的信息,但顯然我不能複製和粘貼。 – Bryan

2

我想創建一個字典從輸入字符串

string input = "DIVIDE = KE48 CLACOS = 4556D DIV = 3466 INT = 4567"; 

var dict = Regex.Matches(input, @"(\w+?) = (.+?)(|$)").Cast<Match>() 
      .ToDictionary(m => m.Groups[1].Value, m => m.Groups[2].Value); 

測試代碼:

foreach(var kv in dict) 
{ 
    Console.WriteLine(kv.Key + "=" + kv.Value); 
} 
相關問題