Reputation: 625
Just having a little problem in attempting a string or regex replace on specific numbers in a string.
For example, in the string
@1 is having lunch with @10 @11
I would like to replace "@1", "@10" and "@11" with the respective values as indicated below.
"@1" replace with "@bob"
"@10" replace with "@joe"
"@11" replace with "@sam"
So the final output would look like
"@bob is having lunch with @joe @sam"
Attempts with
String.Replace("@1", "@bob")
results in the following
@bob is having lunch with @bob0 @bob1
Any thoughts on what the solution might be?
Upvotes: 0
Views: 483
Reputation: 16898
I would prefer more declarative way of doing this. What if there will be another replacements, for example @2
change to luke
? You will have to change the code (add another Replace
call).
My proposition with declarations of the replacements:
string input = "@1 is having lunch with @10 @11";
var rules = new Dictionary<string,string>()
{
{ "@1", "@bob" },
{ "@10", "@joe" },
{ "@11", "@sam"}
};
string output = Regex.Replace(input,
@"@\d+",
match => rules[match.Value]);
Explanation:
Regular expression is searching for pattern @\d+
which means @
followed by one or more digits. And replaces this match thanks to MatchEvaluator
by the proper entry from the rules
dictionary, where the key is the match value itself.
Upvotes: 3
Reputation: 131601
Assuming all placeholder start with @
and contain only digits, you can use the Regex.Replace overload that accepts a MatchEvaluator delegate to pick the replacement value from a dictionary:
var regex = new Regex(@"@\d+");
var dict = new Dictionary<string, string>
{
{"@1","@bob"},
{"@10","@joe"},
{"@11","@sam"},
};
var input = "@1 is having lunch with @10 @11";
var result=regex.Replace(input, m => dict[m.Value]);
The result will be "@bob is having lunch with @joe @sam"
There are a few advantages compared to multiple String.Replace
calls:
@11
must come before @1
)The reason for advantages 3-4 is that the regex will parse the input and create an internal representation that contains the indexes for any match. When the time comes to create the final string, it uses a StringBuilder to read characters from the original string but substitute the replacement values when a match is encountered.
Upvotes: 2
Reputation: 48560
Start with the biggest (read longest) number like @11 and @10 first and then replace @1.
string finalstring = mystring.Replace("@11", "@sam")
.Replace("@10", "@joe")
.Replace("@1", "@bob");
Upvotes: 1
Reputation: 47
Make your regular expression look for the string @1_
The space after will ensure that it only gets the number @1.
Upvotes: 0