3

Is there an easy and elegant way to extract key value pairs from a string of below format?

"key1='value1' key2='value 2' key3='value3' key4='value4' key5='5555' key6='xxx666'"

My attempt resulted in this but I'm not too happy with it

var regex = new Regex(@"\'\s", RegexOptions.None);
var someString = @"key1='value1' key2='value 2' key3='value3' key4='value4' key5='5555' key6='xxx666'" + " ";

var splitArray = regex.Split(someString);

IDictionary<string, string> keyValuePairs = new Dictionary<string, string>();

foreach (var split in splitArray)
{
    regex = new Regex(@"\=\'", RegexOptions.None);

    var keyValuArray = regex.Split(split);

    if (keyValuArray.Length > 1)
    {
        keyValuePairs.Add(keyValuArray[0], keyValuArray[1]);
    }

}
0

3 Answers 3

7

You should be able to do it without a split, using a MatchCollection instead:

var rx = new Regex("([^=\\s]+)='([^']*)'");
var str = "key1='value1' key2='value 2' key3='value3' key4='value4' key5='5555' key6='xxx666'";
foreach (Match m in rx.Matches(str)) {
    Console.WriteLine("{0} {1}", m.Groups[1], m.Groups[2]);
}

Demo.

The heart of this solution is this regular expression: ([^=\\s]+)='([^']*)' It defines the structure of your key-value pair: a sequence of non-space characters defines the key, then there's an equal sign, followed by the value enclosed in single quotes. This solution goes through the matches in sequence, extracting keys and values, which are assigned to matching groups Group[1] and Group[2], in this order.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @dasblinkenlight. That is spot on. Exactly what I was looking for. The explanation helps a lot too. Much appreciated.
2

Another way to do it:

var someString = @"key1='value1' key2='value 2' key3='value3' key4='value4' key5='5555' key6='xxx666'" + " ";
Dictionary<string, string> dic = Regex.Matches(someString, @"(?<key>\w+)='(?<value>[^']*)'")
                                      .OfType<Match>()
                                      .ToDictionary(m => m.Groups["key"].Value, m => m.Groups["value"].Value);

1 Comment

Nice use of 'Named Matched Subexpressions' in the capture groups of the regular expression. And nice use of LINQ, with the 'Enumerable.OfType<TResult>(IEnumerable)' method.
0

You can do it like this

var str = "key1='value1' key2='value 2' key3='value3' key4='value4' key5='5555' key6='xxx666'";
var arr = Regex.Split(str, "(?<=')\\s(?=\\w)"); // split on whitespace to get key=value
foreach(var s in arr) {
    var nArr = s.Split("="); // split on = to get key and value
    keyValuePairs.Add(nArr[0], nArr[1]);
}

(?<=')\s(?=\w) will look for space which is after ' and before the start of the key

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.