I've been doing some parsing with regular expression named capture groups and decided it might make sense to write an extension to handle this.
The code below will create an instance of a specified type and attempt to match the property names to the capture group names and then set the values. It also attempts to cast between compatible types.
Any suggestions for improving this code? Is it ok as an extension?
public static class RegularExpressionExtension
{
public static T CreateType<T>(this Regex regEx, string matchString) where T : new()
{
MatchCollection matchCollection = regEx.Matches(matchString);
T obj = new T();
Type type = typeof(T);
PropertyInfo[] properties = type.GetProperties();
IEnumerable<string> groupNames = regEx.GetGroupNames().Skip(1); //First Group is always 0
if (matchCollection.Count >= 1)
{
SetPropertyValuesFromGroupMatches<T>(groupNames, regEx, obj, matchCollection[0].Groups, properties);
}
return obj;
}
public static IEnumerable<T> CreateTypeCollection<T>(this Regex regEx, string matchString) where T : new()
{
MatchCollection matchCollection = regEx.Matches(matchString);
IEnumerable<string> groupNames = regEx.GetGroupNames().Skip(1); //First Group is always 0
Type type = typeof(T);
PropertyInfo[] properties = type.GetProperties();
foreach (Match match in matchCollection)
{
T obj = new T();
SetPropertyValuesFromGroupMatches<T>(groupNames, regEx, obj, match.Groups, properties);
yield return obj;
}
}
private static void SetPropertyValuesFromGroupMatches<T>(IEnumerable<string> groupNames, Regex regEx, T typeToPopulate, GroupCollection groupCollection, PropertyInfo[] properties)
{
Type type = typeof(T);
foreach (string group in groupNames)
{
var foundProperty = properties.SingleOrDefault(p => p.Name.Equals(group,StringComparison.CurrentCultureIgnoreCase));
if (foundProperty != null)
{
var matchValue = groupCollection[group].Value;
object convertedValue = System.ComponentModel.TypeDescriptor.GetConverter(foundProperty.PropertyType).ConvertFrom(matchValue);
foundProperty.SetValue(typeToPopulate, convertedValue, null);
}
}
}
}