I usually end up with a lot of conditions and/or loops to parse a regex and interpolate values back into its capture groups, and am looking for experienced answers to solve this problem in hopefully a simple manner.
For example, given a regex pattern like X(?<xid>\d+)-(?<xsub>\w+)\.xml
having the named capture groups "xid" and "xsub", intended to match filenames like: X1-foo.xml, X555-bar.xml, etc, when provided with the arguments: int xid=999, string xsub="baz"
, I want to interpolate those values into the pattern groups to construct the proper filename: X999-baz.xml
To keep it simple, explicit captures are not nested.
Without String.Format:
This concept is easily accomplished with .NET String format items like String.Format("X{0}-{1}.xml", xid, xsub)
however I already have a Regex pattern to parse out those values from any filename string, and want to use the same pattern to go in the opposite direction by reconstructing a filename with it, for accuracy. If I require a regex pattern to parse values from a string, but a string with format items to reconstruct the filename, it requires two kinds of distinct syntaxes to be used, creating a greater chance of manual error when writing them - it's too easy to mistakenly create a bad format item string that does not properly reconstruct the result of a regex pattern match, or vice versa.
You can use regex (yay, meta-regexes!):
public static string RegexInterp(Regex pattern, Dictionary<string, string> pairs) {
string regex = pattern.ToString();
string search;
foreach(KeyValuePair<string, string> entry in pairs)
{
// using negative lookbehind so it doesn't match escaped parens
search = @"\(\?<" + entry.Key + @">.*?(?<!\\)\)";
regex = Regex.Replace(regex, search, entry.Value);
}
return Regex.Unescape(unescaped);
}
And then:
Regex rx = new Regex(@"X(?<xid>\d\d+)-(?<xsub>\w+)\.xml");
var values = new Dictionary <string, string>() {{"xid", "999"},
{"xsub", "baz"}} ;
Console.WriteLine(RegexInterp(rx, values));
Prints
X999-baz.xml
Demo: http://ideone.com/QwI2W
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With