Lincoln
Lincoln

Reputation: 759

Regex to parse a list of items

I have a string like (Name := Sam&&Age=:17&& Score:=C6) and a class called Person with around 30 properties - Name, Age, Score, etc. How do I write a regex to parse the string, provided there is a variable number of properties?

Also I was thinking of doing some string replacements to convert the string to a proper JSON and then parse it. Does it sound like a good idea for production code?

I'm using C# 2010.

Upvotes: 0

Views: 1693

Answers (3)

Jacob
Jacob

Reputation: 78840

This regex should match your input string.

\(\s*((?<PropertyName>.*?)\s*((:=)|(=:))\s*(?<PropertyValue>.*?)\s*(&&)?\s*)*\)

Here's what it means:

\(                          Open paren
\s*                         Optional whitespace
(
    (?<PropertyName>.*?)    Property name group
    \s*                     Optional whitespace
    ((:=)|(=:))             Literal ':=' or '=:'
    \s*                     Optional whitespace
    (?<PropertyValue>.*?)   Property value group
    \s*                     Optional whitespace
    (&&)?                   Optional '&&' (the last one won't have one)
    \s*                     Optional whitespace
)*                          The proceeding can repeat 0-many times
\)                          Close paren

With this, you can do a match against your string in C#:

var regex = new Regex(
    @"\(\s*((?<PropertyName>.*?)\s*((:=)|(=:))\s*(?<PropertyValue>.*?)\s*(&&)?\s*)*\)");
var match = regex.Match(yourString);

Then loop through each property/value pair, setting the properties on your object. Setting the object properties will require some reflection and different code based on the object property types:

var properyNames = match.Groups["PropertyName"].Captures;
var properyValues = match.Groups["PropertyValue"].Captures;
var numPairs = propertyNames.Count;

var objType = yourObj.GetType();
for (var i = 0; i < numPairs; i++)
{
    var propertyName = propertyNames[i].Value;
    var theValue = propertyValues[i].Value;

    var property = objType.GetProperty(propertyName);
    object convertedValue = theValue;
    if (property.PropertyType == typeof(int))
        convertedValue = int.Parse(theValue);
    if (property.PropertyType == typeof(DateTime))
        // ....
    // etc....

    property.SetValue(yourObj, convertedValue, null);
}

Upvotes: 1

Babak Naffas
Babak Naffas

Reputation: 12561

If your separator is &&, then I'd do String.Split( "&&", myTextString) when use the regex (\w+)\s*:=\s*(\w+) to isolate the key/value pairs.

Upvotes: 1

CodeZombie
CodeZombie

Reputation: 5377

You should definitely go with the JSON approach. It is much cleaner and robust than relying on a regex.

Take a look at this: Parse JSON in C#

Upvotes: 1

Related Questions