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.
1 Answer 1
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())
);
-
\$\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\$Matthias Burger– Matthias Burger2017年02月08日 14:56:48 +00:00Commented Feb 8, 2017 at 14:56
PatternReplace1
,PatternReplace2
, etc? nooo) \$\endgroup\$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\$Func<string[], string>
overload (sacrifyng readability) \$\endgroup\$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 theRegex
-class if I got more than 4 params \$\endgroup\$