regex string extension I wrote some string-extensions:

public static class RegexStringExtensions
{
    public static string PatternReplace(
        this string seed, string pattern, 
        Func&lt;string, string&gt; outPattern)
    {
        return Regex.Replace(seed, pattern, s =&gt; outPattern(s.Groups[1].Value));
    }

    public static string PatternReplace(
        this string seed, string pattern, 
        Func&lt;string, string, string&gt; outPattern)
    {
        return Regex.Replace(seed, pattern, s =&gt; outPattern(s.Groups[1].Value, s.Groups[2].Value));
    }
    public static string PatternReplace(
        this string seed, string pattern, 
        Func&lt;string, string, string, string&gt; outPattern)
    {
        return Regex.Replace(seed, pattern, s =&gt; outPattern(s.Groups[1].Value, s.Groups[2].Value, s.Groups[3].Value));
    }
    public static string PatternReplace(
        this string seed, string pattern, 
        Func&lt;string, string, string, string, string&gt; outPattern)
    {
        return Regex.Replace(seed, pattern, s =&gt; outPattern(s.Groups[1].Value, s.Groups[2].Value, s.Groups[3].Value, s.Groups[4].Value));
    }
}


with those, I could handle a replacement for regex-pattern and work with the groups more in C#-way like (just an easy example):

string val = 
    "abcdef".PatternReplace(@"(ab)(cd)(ef)", (s,t,u) =&gt; u + string.Concat(s.Reverse()));
// result is "efba"


I think it's not that nice, to have so many overloads since I could have like 10 groups or something.
Any idea how I could make this a bit nicer?
For now, it'd work with up to 4 parameters, but with also 4 overloads.
I'm not saying I like this but you could reuse the longest overload for the shorter ones. Here I took the one that takes three parameters.

public static string PatternReplace(
    this string seed, 
    string pattern,
    Func&lt;string, string&gt; outPattern
)
{
    return seed.PatternReplace(pattern, (x, y, z) =&gt; outPattern(x));
}

public static string PatternReplace(
    this string seed, 
    string pattern,
    Func&lt;string, string, string&gt; outPattern
)
{
    return seed.PatternReplace(pattern, (x, y, z) =&gt; outPattern(x, y));
}




Here's another small experiment with C# 7 where you could use anonymous tuples with only one method. But actually you could return a tuple in you current solution too.

public static class RegexStringExtensions
{   
    public static string PatternReplace(
        this string seed, 
        string pattern,
        Func&lt;(string, string, string), string&gt; outPattern
    )
    {
        return Regex.Replace(
            seed, 
            pattern, 
            m =&gt; outPattern((
                m.Groups[1].Value, 
                m.Groups[2].Value, 
                m.Groups[3].Value)
            )
        );
    }
}


Usage:

string val = "abcdef".PatternReplace(
    @"(ab)(cd)(ef)", 
    t =&gt; t.Item1 + string.Concat(t.Item2.Reverse())
);