file.cs

January 25, 2016 ยท View on GitHub

public class EmailAddress { [Match("^")] public string _; [Match(@"\w+")] public string User; [Match("@")] public string _1; [Match("[^@]+")] public string Host; [Match("$")] public string _2; }

public static class Matcher
{
    public static T Match<T>(string input) where T: new()
    {
        var props = typeof (T).GetFields()
            .Select(x => new {
                Attr = x.GetCustomAttributes(typeof (MatchAttribute), false).Cast<MatchAttribute>().First(),
                Prop = x
            }).OrderBy(x => x.Attr.Order);
        var re = string.Join("", 
            props.Select(x => new {x.Attr.Pattern, x.Prop.Name}).
            Select(x => x.Name.StartsWith("_") ? (x.Pattern) : $"({x.Pattern})"));
        var match = Regex.Match(input, re);
        var res = new T();
        var toFill = props.Where(x => !x.Prop.Name.StartsWith("_")).ToList();
        for(var i = 0; i < toFill.Count(); i++)
        {
            toFill[i].Prop.SetValue(res, match.Groups[i].Value);
        }
        
        return res;
    }
}
[AttributeUsage(AttributeTargets.Field)]
public sealed class MatchAttribute : Attribute
{
    public MatchAttribute(string pattern, [CallerLineNumber] int order = 0)
    {
        Order = order;
        Pattern = pattern;
    }
    public string Pattern { get;  }
    public int Order { get; }
}

class Program
{
    
    static void Main(string[] args)
    {
        var addr = Matcher.Match<EmailAddress>("benji@tipranks.com");
       
        Console.WriteLine("Done");
    }
}