0

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.

Babak Naffas
  • 12,395
  • 3
  • 34
  • 49
Lincoln
  • 749
  • 1
  • 7
  • 13

3 Answers3

1

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#

Community
  • 1
  • 1
CodeZombie
  • 5,367
  • 3
  • 30
  • 37
1

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.

Babak Naffas
  • 12,395
  • 3
  • 34
  • 49
1

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);
}
Jacob
  • 77,566
  • 24
  • 149
  • 228
  • Thanks Jacob, very nice :) What do you think about the conversion to valid JSON, looks like the code will be shorter, but I'm not sure about performance and reliability? – Lincoln Nov 12 '11 at 01:01
  • I wouldn't bother with converting to JSON before parsing; would be some extra unnecessary work, and it can be tricky (you have to deal with escaping some characters). – Jacob Nov 12 '11 at 16:03