Effective way of splitting strings

I have a completed line 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++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: 

this line is like this

  • This is a list of PO (payment options) that are separated ~~
  • this list may contain one or more OP
  • PO contains only key pairs, separated by :
  • spaces are indicated by ++

I need to extract the values ​​for the "RGI" and "N" keys.

I can do this through a loop, I want an efficient way to do this. any help on this.

Edit: from ~ ~ to ~~

+4
source share
6 answers

Listen, I'll go. I used regular expressions for a reasonable amount of text, which they transform 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]); } } 
+1
source

I don't know if it is more efficient than RegEx, but the LINQ to Objects alternative is used here.

 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(); 
+3
source

I think you should try regex. Since you are using C #, check out this handy .NET list for .NET registries .

+2
source

You can parse a string in a dictionary and then pull 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); } 
+2
source

Here is an attempt to search by index: (I prefer that I add my LINQ solution)

 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 the 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 arrays for each element that contains a pair of key values ​​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 delete Where , and it will include all the keys and their values.

+1
source

Use string.Split() on ":" to extract key-value pairs.

Then extract as you need. If the positions in the string are not fixed, you will need to search for each element in the resulting string[] array for a particular key.

If you need to search often, I would consider the separation of key-value pairs and placement in some kind of dictionary.

0
source

Source: https://habr.com/ru/post/1310586/


All Articles