Reputation: 49
Please, I want to replace a class properties (or fields) in string, I want to use Regex, but I'am not familiarised with regular expressions. Example of string :
string Source = "Dear @Customer.Civility, @Customer.Name @Customer.Surname\n\n " +
"About your bill dated @Order.Date..."
I want to catch the occurences of classes properties like "@Customer.Name" , "@Order.Date" and replace them with its values using reflections.
Is there AnyOne to Help me, Please ( Excuse my English...)
Upvotes: 0
Views: 1481
Reputation: 4239
This is actually interesting challenge. I used Matt's regex.
var customer = new Customer() { Civility = "Mr.", Name = "Max", Surname = "Mustermann" };
var order = new Order();
string Source = "Dear @Customer.Civility, @Customer.Name @Customer.Surname\n\n About your bill dated @Order.Date...";
string s = BringTheMash(Source, new { Customer = customer, Order = order });
Console.WriteLine(s);
private static string BringTheMash(string format, object p)
{
string result = format;
var regex = new Regex(@"@(?<object>\w+)\.?(?<property>\w+)");
foreach (Match m in regex.Matches(format))
{
var obj = m.Groups[1].ToString();
var prop = m.Groups[2].ToString();
var parameter = p.GetType().GetProperty(obj).GetValue(p);
var value = parameter.GetType().GetProperty(prop).GetValue(parameter);
result = result.Replace(m.Value, value.ToString());
}
return result;
}
I didn't add any exception handling, which would happen if objects didn't have required properties.
Upvotes: 4
Reputation: 45135
Aside from the comments on why regex might not be the right solution, if you do need a regex (because you need this to be more dynamic, maybe processing several templates for example), something like:
@\w+\.?\w+
Ought to do the trick.
It matches the literal @
followed by 1 or more word characters (\w
is shorthand for the class [A-Za-z0-9_]
, i.e. all the letters, digits and the underscore, which should cover you), followed by an optional .
(just remove the ?
if you want it to be non-optional) and then 1 or more word characters.
You can use it like this:
var regex = new Regex(@"@\w+\.?\w+");
string Source = "Dear @Customer.Civility, @Customer.Name @Customer.Surname\n\n " +
"About your bill dated @Order.Date...";
foreach(Match m in regex.Matches(Source))
{
// do whatever processing you want with the matches here.
Console.WriteLine(string.Format("{0}:{1}",m.Index,m.Value));
}
Logs:
5:@Customer.Civility
25:@Customer.Name
40:@Customer.Surname
82:@Order.Date
With the index and the text of the match, you should have everything you need to make your replacements.
If you want to make it easier to extract the object and the property from your matches, you can use grouping in your regex. Something like this:
var regex = new Regex(@"@(?<object>\w+)\.?(?<property>\w+)");
string Source = "Dear @Customer.Civility, @Customer.Name @Customer.Surname\n\n " +
"About your bill dated @Order.Date...";
foreach(Match m in regex.Matches(Source))
{
Console.WriteLine(string.Format("Index: {0}, Object: {1}, Property: {2}",
m.Index,m.Groups["object"],m.Groups["property"]));
}
Will log:
Index: 5, Object: Customer, Property: Civility
Index: 25, Object: Customer, Property: Name
Index: 40, Object: Customer, Property: Surname
Index: 82, Object: Order, Property: Date
So now you've identified the index, the object that you need to get the substitution from and the property you need from that object.
Upvotes: 2
Reputation: 26846
Are you really want to go such a complicated way?
Why just don't have a string like
string Source = "Dear {0}, {1} {2}\n\n " + "About your bill dated {3}..."
and later format it like
string result = string.Format(Source,
Customer.Civility,
Customer.Name,
Customer.Surname,
Order.Date)
Upvotes: 2