2010-05-22 70 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();