Introduction
Let me demonstrate a powerful, but quite unknown overload of Regex.Replace()
.
I won't go into Regex-Programming in Detail - hopefully you are familiar with that, or you'll find a good Resource on the Internet.
The demand is - as stated here - to convert format-strings for the C-sprintf(format, <arglist>)
- Function to format-strings, which are applicable to the .NET- string.Format(
format, <arglist>)
-Function.
For instance, the C formatstring:
"%s shoots a %s at you for %d damage!"
is to convert to:
"{0} shoots a {1} at you for {2} damage!"
Code
1 using System.Text.RegularExpressions;
2 private static Regex _rgxPrint2Format = new Regex("%[sd]");
4
5 private static string Sprint(string format,params object[] args) {
6 var counter = 0;
7 MatchEvaluator match2String = mt => string.Concat("{", counter++, "}");
8 return string.Format(_rgxPrint2Format.Replace(format, match2String), args);
9 }
You see: the problem is solved in 4 lines of code. To understand the solution, there is to understand, what a Matchevaluator
is - see its definition in ObjectBrowser (<-follow the link, if you don't know the OB):
public delegate string MatchEvaluator(RegularExpressions.Match match)
It is a Delegate
of a function, which converts a Regex.Match
to a string
.
In the code above, line#7, the function, targeted by the delegate is directly noted as anonymous Function within the same line, and it replaces the Match
by "{<counter>}"
, then increments counter
- that's all.
Next Line I pass my converter to _rgxPrint2Format.Replace(,)
which applies it to each occurring match.
Means: The Regex finds the matches, the converter converts them to .NET-like placeholders, and therefore the .NET- string.Format()
- method can apply the converted format-instructions to the args
.
Code Usage
private void Test() {
var output = Sprint("%s %s", "hello", "World");
Console.WriteLine(output);
output = Sprint("%s", "hello", "World");
Console.WriteLine(output);
output = Sprint("%s %d", "hello", "World", 23);
Console.WriteLine(output);
output = Sprint("%s %s %d", "hello", "World", 23);
Console.WriteLine(output);
output = Sprint("%s shoots a %s at you for %d damage!",
"lakedoo2310", "fireball", 99);
Console.WriteLine(output);
}
The output is as expected:
hello World
hello
hello World
hello World 23
lakedoo2310 shoots a fireball at you for 99 damage!