2010-05-22 79 views
4

我有一個完整的字符串,這樣字符串分割的有效方式

N:Pay in Cash++RGI:40++R:200++T:Purchase++IP:N++IS:N++PD:PC++UCP:598.80++UPP:0.00++TCP:598.80++TPP:0.00++QE:1++QS:1++CPC:USD++PPC:Points++D:Y++E:Y++IFE:Y++AD:Y++IR:++MV:++CP:~~ N:ERedemption++RGI:42++R:200++T:Purchase++IP:N++IS:N++PD:PC++UCP:598.80++UPP:0.00++TCP:598.80++TPP:0.00++QE:1++QS:1++CPC:USD++PPC:Points++D:Y++E:Y++IFE:Y++AD:Y++IR:++MV:++CP: 

這個字符串就是這樣

  1. 這是PO的(付款方式)的列表,它是由~~
  2. 分離
  3. 此列表可能包含一個或多個OP
  4. PO僅包含由分隔的鍵 - 值對:
  5. 空間由++

我需要提取的值密鑰 「RGI」 和 「N」 表示。

我可以通過for循環,我想要一個有效的方式來做到這一點。 對此有幫助。

編輯:從〜〜到~~

+2

該描述與字符串不匹配。 – 2010-05-22 04:51:10

+0

啊好老EDI。 – 2010-05-22 05:59:09

+0

哪部分是誤導的 – Posto 2010-05-22 06:23:50

回答

1

聽到雅去我用正則表達式和一個合理數量的文本,他們預製好。

static void Main(string[] args) 
{ 
    string str = @"N:Pay in Cash++RGI:40++R:200++T:Purchase++IP:N++IS:N++PD:PC++UCP:598.80++UPP:0.00++TCP:598.80++TPP:0.00++QE:1++QS:1++CPC:USD++PPC:Points++D:Y++E:Y++IFE:Y++AD:Y++IR:++MV:++CP:~ ~N:ERedemption++RGI:42++R:200++T:Purchase++IP:N++IS:N++PD:PC++UCP:598.80++UPP:0.00++TCP:598.80++TPP:0.00++QE:1++QS:1++CPC:USD++PPC:Points++D:Y++E:Y++IFE:Y++AD:Y++IR:++MV:++CP:"; 
    System.Text.RegularExpressions.MatchCollection MC = System.Text.RegularExpressions.Regex.Matches(str,@"((RGI|N):.*?)\+\+"); 
    foreach(Match Foundmatch in MC) 
    { 
     string[] s = Foundmatch.Groups[1].Value.Split(':'); 
     Console.WriteLine("Key {0} Value {1} " ,s[0],s[1]); 

    } 

} 
2

我想你應該嘗試一個正則表達式。由於您使用的是C#,請查看this handy .NET RegEx cheat sheet

+0

+1 - 尼斯鏈接謝謝。 – 2010-05-22 09:38:43

0

在「:」上使用string.Split()來提取鍵值對。

然後根據需要提取它們。如果字符串中的位置不固定,則需要搜索生成的string[]陣列中的每個項目以獲取特定鍵。

如果您需要經常搜索,我會考慮拆分鍵值對並放置在某種字典中。

2

你可以解析字符串轉換成字典,然後拉你的價值觀......

string s = "N:Pay in Cash++RGI:40++R:200++"; 

// Replace "++" with "," 
s.Replace("++",","); 

// Divide all pairs (remove empty strings) 
string[] tokens = s.Split(new char[] { ':', ',' }, StringSplitOptions.RemoveEmptyEntries); 

Dictionary<string, string> d = new Dictionary<string, string>(); 

for (int i = 0; i < tokens.Length; i += 2) 
{ 
    string key = tokens[i]; 
    string value = tokens[i + 1]; 

    d.Add(key,value); 
} 
+0

+1儘管OP要求採用無迴路解決方案,但這很容易理解[2],當老闆說「你也可以在你身邊的時候抓住UCP值」的時候,它仍然可以工作嗎? – egrunin 2010-05-22 05:33:47

1

這裏是基於指數的嘗試做一個搜索:(我喜歡我的LINQ的解決方案,我加)

string test = "N:Pay in Cash++RGI:40++R:200++T:Purchase++IP:N++IS:N++PD:PC++UCP:598.80++UPP:0.00++TCP:598.80++TPP:0.00++QE:1++QS:1++CPC:USD++PPC:Points++D:Y++E:Y++IFE:Y++AD:Y++IR:++MV:++CP:~ ~N:ERedemption++RGI:42++R:200++T:Purchase++IP:N++IS:N++PD:PC++UCP:598.80++UPP:0.00++TCP:598.80++TPP:0.00++QE:1++QS:1++CPC:USD++PPC:Points++D:Y++E:Y++IFE:Y++AD:Y++IR:++MV:++CP:"; 
string[] parts = test.Split(new string[] { "~ ~" }, StringSplitOptions.None);    
var result = parts.Select(p => new 
{ 
    N = p.Substring(p.IndexOf("N:") + 2, 
     p.IndexOf("++") - (p.IndexOf("N:") + 2)), 
    RGI = p.Substring(p.IndexOf("RGI:") + 4, 
     p.IndexOf("++", p.IndexOf("RGI:")) - (p.IndexOf("RGI:") + 4)) 
}); 

創建兩個對象的列表與以下值:

result = {{N = "Pay in Cash", RDI = 40}, {N = "ERedemption", RDI = 42}} 

編輯:解決方案使用LINQ

我決定嘗試使用LINQ做的這一切,這裏是我想出了:

string test = "N:Pay in Cash++RGI:40++R:200++T:Purchase++IP:N++IS:N++PD:PC++UCP:598.80++UPP:0.00++TCP:598.80++TPP:0.00++QE:1++QS:1++CPC:USD++PPC:Points++D:Y++E:Y++IFE:Y++AD:Y++IR:++MV:++CP:~ ~N:ERedemption++RGI:42++R:200++T:Purchase++IP:N++IS:N++PD:PC++UCP:598.80++UPP:0.00++TCP:598.80++TPP:0.00++QE:1++QS:1++CPC:USD++PPC:Points++D:Y++E:Y++IFE:Y++AD:Y++IR:++MV:++CP:"; 

var result = test.Split(new string[] { "~ ~" }, StringSplitOptions.None). 
    Select(m => m.Split(new string[] { "++" }, StringSplitOptions.None)). 
    Select(p => p.Select(i => i.Split(':')). 
     Where(o => o[0].Equals("N") || o[0].Equals("RGI")). 
     Select(r => new { Key = r[0], Value = r[1]})); 

它生產和數組包含每個項目只有N和RGI的關鍵值對。

result = {{{Key = "N", Value = "Pay in Cash"}, {Key = "RDI", Value = 40}}, 
      {{Key = "N", Value = "ERedemption"}, {Key = "RDI", Value = 42}}} 

如果你願意,你可以刪除Where,這將包括所有這些鍵及其值。

3

不知道它是否比RegEx更有效,但是這裏有一個使用LINQ to Objects的替代方法。

KeyValuePair<string, string>[] ns = (from po in pos.Split(new string[] { "~~" }, StringSplitOptions.RemoveEmptyEntries) 
            from op in po.Split(new string[] { "++" }, StringSplitOptions.RemoveEmptyEntries) 
            where op.StartsWith("N:") || op.StartsWith("RGI:") 
            let op_split = op.Split(':') 
            select new KeyValuePair<string, string>(op_split[0], op_split[1])).ToArray();