Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to extract a dynamic object from a variable template string and merge it in again?

I have a string.

This string is extracted from a file at runtime and can be anything with it's format being the one in the example below.

The only rule is that words inside brackets have to be converted to properties on a dynamic object and it's values asked from the user, probably by using a winforms PropertyGrid or an ObjectListView. The user's answers will then be merged into the string template (maybe using FormattableStringFactory.Create ?).

Example strings:

string template = "The client name is {name} and the client's age is {age}";
string template2 = "This house is on {streetName} and the door number is {doorNumber}";

Object extraction:

dynamic templateObject = objectExtractor (templateString);

Final string (after data is introduced into the templateObject by the user):

string result = "The client name is John and the client's age is 25";

In other words, what i want to do is similar to what C# 6 compiler does with it's string interpolation syntactic sugar.

I'm looking for a way (a simple generic one, preferably) to do it but i can't figure it out myself and haven't found it after some extensive googling.

like image 749
osiris Avatar asked Dec 09 '25 11:12

osiris


1 Answers

String interpolation is String.Format in a different form.
You could replace the elements in the template string with numbered placeholders and use String.Format() to format the string using an array of values, determined by a User input, that replace the placeholders:

int matchCount = 0;
string temp = Regex.Replace(template, @"\{.*?\}", (Match m)=> $"{{{matchCount++}}}");
string result = string.Format(temp, new[] {input1, input2});

Where new[] {input1, input2} represent the array of inputs used as replacement.
Of course the array of values can be built beforehand:

var userInputs = new string[] { input1, input2, inputN };
string result = string.Format(temp, userInputs);

Then it depends on how the your objectExtractor works. You can use Regex.Matches, with the same pattern, to extract the original placeholders from the template string and determine the number of inputs and their type, which can be based on the name of each placeholder, using, e.g., a Dictionary<string, Control> to map a string selector to an input Control or whatever else.

For example, using a Dictionary to map placeholders with TextBox Controls:

var maps = new Dictionary<string, Control>() {
    ["{name}"] = textBox1,
    ["{age}"] = textBox2,
};

string[] parameters = 
    Regex.Matches(template, @"\{.*?\}").OfType<Match>().Select(m => m.Value).ToArray();

string[] userInputs = parameters.Select(s => maps[s].Text).ToArray();
string result = string.Format(temp, userInputs);
like image 199
Jimi Avatar answered Dec 12 '25 03:12

Jimi