patterncsharpMinor
Extension Method for Creating Types from Regular Expression Match Groups
Viewed 0 times
expressiongroupsmethodcreatingregularmatchextensionfortypesfrom
Problem
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(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 groupNames = regEx.GetGroupNames().Skip(1); //First Group is always 0
if (matchCollection.Count >= 1)
{
SetPropertyValuesFromGroupMatches(groupNames, regEx, obj, matchCollection[0].Groups, properties);
}
return obj;
}
public static IEnumerable CreateTypeCollection(this Regex regEx, string matchString) where T : new()
{
MatchCollection matchCollection = regEx.Matches(matchString);
IEnumerable 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(groupNames, regEx, obj, match.Groups, properties);
yield return obj;
}
}
private static void SetPropertyValuesFromGroupMatches(IEnumerable 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.Curre
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(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 groupNames = regEx.GetGroupNames().Skip(1); //First Group is always 0
if (matchCollection.Count >= 1)
{
SetPropertyValuesFromGroupMatches(groupNames, regEx, obj, matchCollection[0].Groups, properties);
}
return obj;
}
public static IEnumerable CreateTypeCollection(this Regex regEx, string matchString) where T : new()
{
MatchCollection matchCollection = regEx.Matches(matchString);
IEnumerable 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(groupNames, regEx, obj, match.Groups, properties);
yield return obj;
}
}
private static void SetPropertyValuesFromGroupMatches(IEnumerable 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.Curre
Solution
If you are doing reflection magics the caller of your method may be as well. If that person already has a
Type it can be a bit of a pain in the butt to call your generic method. Since you are already working against a Type offering an overload for it should not be too much work. Perhaps extracting the following code into its own method may help:PropertyInfo[] properties = type.GetProperties();
IEnumerable groupNames = regEx.GetGroupNames().Skip(1); //First Group is always 0
if (matchCollection.Count >= 1) {
SetPropertyValuesFromGroupMatches(groupNames, regEx, obj, matchCollection[0].Groups, properties);
}Code Snippets
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);
}Context
StackExchange Code Review Q#13731, answer score: 2
Revisions (0)
No revisions yet.