-3

I have a string which is split twice in array. Here is an example:

Obj1:Val1|Obj2:Val2|Obj3:Val3

Please help me with the regular expression to fetch the array of first string:

Obj1
Obj2
Obj3

And then another regex to fetch

Val1
Val2
Val3

I do not want to iterate. I want the result from regex in one go.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
Ankit
  • 6,388
  • 8
  • 54
  • 79

5 Answers5

1

Since you are using C# you can first split your string with | then you will have list of strings with : as those delimiter so you can then split the sub lists with : and use zip function to get the list of objects and values.

But as a straight way you can use following regexes :

for values (the first group):

:(.*?)(\||$)

for objects (the second group):

(\||^)(.*?):
Community
  • 1
  • 1
Mazdak
  • 105,000
  • 18
  • 159
  • 188
1

You can use the following to split:

[:|]

And even indexes will give Obj1 Obj2 Obj3 and fetch Val1 Val2 Val3 from odd indexes of the array

Or..

You can split the regex with [|] and then split each value with [:].. storing [0] in one array and [1] in another array..

Edit:

For list of Obj's you can split with following regex:

:\w+(?:\||$)

For list of Val's you can split with foloowing regex:

(?:^|\|)\w+:
karthik manchala
  • 13,492
  • 1
  • 31
  • 55
1

Use named match captures to extract the information. The below regex gets the key value (the first one) and the value value (the second one) and ultimately creates Key Value pair object.

string data ="Obj1:Val1|Obj2:Val2|Obj3:Val3";
string pattern = @"(?<Key>[^:]+):(?<Value>[^|]+)+\|?";

  Regex.Matches(data, pattern)
       .OfType<Match>()
       .Select (mt => new KeyValuePair<string,string>(mt.Groups["Key"].Value,  
                                                      mt.Groups["Value"].Value) );

Note the KeyValuePair projection is optional, you can simply extract the information via mt.Groups["Key"].Value on its own.

Here is the result of the above regex/linq projection:

enter image description here

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
1

You do not need a regex. Use Split and LINQ:

var str = "Obj1:Val1|Obj2:Val2|Obj3:Val3";
var arr = str.Split(new[] {'|',':'});
// And then either these 2 lines to get Objs and Vals into different arrays
var vals  = arr.Where((c,i) => i % 2 != 0).ToArray();
var objs = arr.Where((c,i) => i % 2 == 0).ToArray();
// Or into a key-value pair array
var key_value_array = 
     arr.Where((c, i) => i % 2 == 0)
        .Zip(arr.Where((c, i) => i % 2 != 0), 
             (key, value) => new KeyValuePair<string, string>(key, value))
        .ToArray();

Output:

enter image description here enter image description here enter image description here

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Calling `ToList()` on `arr` is unnecessary because the underlying object is not *queryable*; for split returns a enumerable string[] result. – ΩmegaMan May 26 '15 at 19:26
  • Yes, You are right. No need converting `string[]` to `List`, updated. I just was not sure, and had no way to check. – Wiktor Stribiżew May 26 '15 at 19:34
  • Use Linqpad. Also add this to your answer to `Zip` up the results into a KeyValue pair: `arr.Where((c,i) => i % 2 != 0) .Zip(arr.ToList().Where((c,i) => i % 2 == 0) , (key, value) => new KeyValuePair(key,value))` – ΩmegaMan May 26 '15 at 19:35
  • Oops reverse my logic on the where, for key and value. – ΩmegaMan May 26 '15 at 19:38
  • @OmegaMan: Thank you for the hint. Now, it seems there is plenty of choice for OP :) – Wiktor Stribiżew May 26 '15 at 19:43
  • I require a regex and not a LINQ. It again iterates through – Ankit May 27 '15 at 18:48
  • Please describe a solution you are seeking. It is not clear now how you want it to be done. Please show us the code you are using, it may help us understand your approach. – Wiktor Stribiżew May 27 '15 at 18:55
0

To get Obj matches you can split by:

:[^|]+(?:\||$)

And to get Val strings split by:

(^|\|)[^:]+:
anubhava
  • 761,203
  • 64
  • 569
  • 643