Effective way of String splitting
I have a completed string like this
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++TC开发者_C百科P:598.80++TPP:0.00++QE:1++QS:1++CPC:USD++PPC:Points++D:Y++E:Y++IFE:Y++AD:Y++IR:++MV:++CP:
this string is like this
- It's list of PO's(Payment Options) which are separated by ~~
- this list may contains one or more OP
- PO contains only Key-Value Pairs which separated by :
- spaces are denoted by ++
I need to extract the values for Key "RGI" and "N".
I can do it via for loop , I want a efficient way to do this. any help on this.
Edit: from ~ ~ To ~~
Don't know if it's more efficient than RegEx, but here's a alternative using 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();
I think you should try a regular expression. Since you are using C#, check out this handy .NET RegEx cheat sheet.
You could parse the string into a dictionary and then pull in your values...
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);
}
hear ya go I used regular expressions and for a reasonable amount of text they preform well.
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]);
}
}
Here is an attempt doing a search based on index: (I prefer my LINQ solution that I added)
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))
});
Creates a list of two objects with following values:
result = {{N = "Pay in Cash", RDI = 40}, {N = "ERedemption", RDI = 42}}
EDIT: SOLUTION USING LINQ
I decided to try and do it all with LINQ and here is what I came up with:
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]}));
It produces and array for each item that contains a Key Value pair of only N and RGI.
result = {{{Key = "N", Value = "Pay in Cash"}, {Key = "RDI", Value = 40}},
{{Key = "N", Value = "ERedemption"}, {Key = "RDI", Value = 42}}}
If you want you can remove the Where
and it will include all they Keys and their Values.
Use string.Split()
on ":" to extract the key-value pairs.
Then extract as you need them. If the positions in the string are not fixed,you will need to search each item in the resulting string[]
array for a particular key.
If you need to search often, I would consider splitting the key-value pairs and placing in some sort of Dictionary.
精彩评论