2
\$\begingroup\$

I wrote some string-extensions:

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

    public static string PatternReplace(
        this string seed, string pattern, 
        Func<string, string, string> outPattern)
    {
        return Regex.Replace(seed, pattern, s => outPattern(s.Groups[1].Value, s.Groups[2].Value));
    }
    public static string PatternReplace(
        this string seed, string pattern, 
        Func<string, string, string, string> outPattern)
    {
        return Regex.Replace(seed, pattern, s => outPattern(s.Groups[1].Value, s.Groups[2].Value, s.Groups[3].Value));
    }
    public static string PatternReplace(
        this string seed, string pattern, 
        Func<string, string, string, string, string> outPattern)
    {
        return Regex.Replace(seed, pattern, s => 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) => 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.

\$\endgroup\$
4
  • \$\begingroup\$ What's bad with those overloads? If you need an extra parameter you just add it to your lambda, no need to also change method name (PatternReplace1, PatternReplace2, etc? nooo) \$\endgroup\$ Commented Feb 8, 2017 at 14:19
  • \$\begingroup\$ @AdrianoRepetti would be nice to have something like params for generics. would save me a lot of code...- so you wouldn't change anything and just go with e.g. 10 overloads? \$\endgroup\$ Commented Feb 8, 2017 at 14:22
  • \$\begingroup\$ Honestly I'd stop with 2 overloads (3 at maximum). At the calling point a lambda with so many parameters will be (IMO) pretty hard to read and a traditional approach preferable. Well, it's just my POV. Note that nothing stops you to have an extra Func<string[], string> overload (sacrifyng readability) \$\endgroup\$ Commented Feb 8, 2017 at 14:35
  • \$\begingroup\$ a lambda with so many parameters will be (IMO) pretty hard to read good point! Mh I think I will go with only 4 parameters. I don't think I will ever use more than 4 groups... otherwise I simply will use the Regex-class if I got more than 4 params \$\endgroup\$ Commented Feb 8, 2017 at 14:39

1 Answer 1

1
\$\begingroup\$

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<string, string> outPattern
)
{
    return seed.PatternReplace(pattern, (x, y, z) => outPattern(x));
}

public static string PatternReplace(
    this string seed, 
    string pattern,
    Func<string, string, string> outPattern
)
{
    return seed.PatternReplace(pattern, (x, y, z) => 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<(string, string, string), string> outPattern
    )
    {
        return Regex.Replace(
            seed, 
            pattern, 
            m => outPattern((
                m.Groups[1].Value, 
                m.Groups[2].Value, 
                m.Groups[3].Value)
            )
        );
    }
}

Usage:

string val = "abcdef".PatternReplace(
    @"(ab)(cd)(ef)", 
    t => t.Item1 + string.Concat(t.Item2.Reverse())
);
\$\endgroup\$
1
  • \$\begingroup\$ wow, okay, that's an approach I could experiment with. Didn't know working with s.th. like Func<(string, string, string), string> (but first, need to check for C#7) \$\endgroup\$ Commented Feb 8, 2017 at 14:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.