C# String replace with dictionary
If the data is tokenized (i.e. "Dear $name$, as of $date$ your balance is $amount$"), then a Regex
can be useful:
static readonly Regex re = new Regex(@"\$(\w+)\$", RegexOptions.Compiled);
static void Main() {
string input = @"Dear $name$, as of $date$ your balance is $amount$";
var args = new Dictionary<string, string>(
StringComparer.OrdinalIgnoreCase) {
{"name", "Mr Smith"},
{"date", "05 Aug 2009"},
{"amount", "GBP200"}
};
string output = re.Replace(input, match => args[match.Groups[1].Value]);
}
However, without something like this, I expect that your Replace
loop is probably about as much as you can do, without going to extreme lengths. If it isn't tokenized, perhaps profile it; is the Replace
actually a problem?
Replacing words in a string with values from Dictionary in c#
Simply:
var output = new StringBuilder(fruitString);
foreach (var kvp in fruitDictionary)
output.Replace(kvp.Key, kvp.Value);
var result = output.ToString();
This simply initializes a StringBuilder
with your fruitString
, and iterates over the Dictionary
, replacing each key it finds with the value.
Replacing text with a string using a dictionary
In your loop
foreach (KeyValuePair<string, string> entry in items)
{
replacedContent = Regex.Replace(contentFile, entry.Key, entry.Value);
}
you are assigning the result to replacedContent
in each iteration. The replacement result that was previously stored in replacedContent
is overwritten in the next iteration, since you are not reusing the previous result. You have to reuse the variable that stores the string in the foreach
loop:
replacedContent = sr.ReadToEnd();
foreach (KeyValuePair<string, string> entry in items)
{
replacedContent = Regex.Replace(replacedContent, entry.Key, entry.Value);
}
Replace String with Dictionary c#
Just expand your lambda:
var args = new Dictionary<string, string> {
{"text1", "name"},
{"text2", "Franco"}
};
saveText(Regex.Replace("Hi, my {text1} is {text2}.", @"\{(\w+)\}", m => {
string value;
return args.TryGetValue(m.Groups[1].Value, out value) ? value : "null";
}));
Replacing a dictionary key in a string with the value
I suggest using regular expressions and matching instead of Split
, which can help out us when we have punctuation, e.g.
Call me ASAP!
Regex can well extract "ASAP"
which we can substitute from the dictionary as as soon as possible
; when Split
will return {"Call", "me", "ASAP!"}
and we are in troubles with "ASAP!"
Code:
using System.Text.RegularExpressions;
...
//DONE:
// 1. ReadLines - we don't want premature materialization
// 2. Split(..2..) - no more then 2 items (in case text has commas)
private m_Dictionary = File
.ReadLines("textwords.csv")
.Select(x => x.Split(",", 2, StringSplitOptions.RemoveEmptyEntries | ))
.Where(pair => pair.Length == 2)
.ToDictionary(pair => pair[0], pair => pair[1]);
//DONE: business logic only, no UI
public string changeAbbreviations(string content,
IDictionary<string, string> dictionary = null) {
dictionary = dictionary ?? m_Dictionary;
if (string.IsNullOrEmpty(content))
return content;
// We try to change all uppercase words like ASAP, LOL etc.
return Regex.Replace(content, @"\b\p{Lu}+\b", match =>
dictionary.TryGetValue(match.Value, out var text)
? text
: match.Value);
}
// UI only
private void btnFilter_Click(object sender, RoutedEventArgs e) {
txtContentClean.Text = changeAbbreviations(txtContentClean.Text);
}
Edit: If we allow digits within abbreviations, like "P2P", "I18N"
, "M8"
the pattern can be
\b(?:\p{Lu}+[0-9]*)+\b
I.e
...
return Regex.Replace(content, @"\b(?:\p{Lu}+[0-9]*)+\b", match =>
dictionary.TryGetValue(match.Value, out var text)
? text
: match.Value);
...
String replace with recursive dictionary values
I think your regex solution was quite close, you just need to check to see if you found any values in the dictionary when you did the replace and if you did then call it recursively.
public static string EvaluateStringWithVariables(string strExpr)
{
Dictionary<string, string> variables = new Dictionary<string, string>()
{
{ "clientRefUrl", "[clientBaseUrl]/RealtimeReferenceData"},
{ "clientRealtimeUrl", "[clientBaseUrl]/RealtimeClinicalData"},
{ "localApiUrl", "LocalApi/Generic"},
{ "integrationRootFolder", "C:\\LocalServer\\Integration"},
{ "clientBaseUrl", "https://company.com/api"},
{ "clientAuthBaseUrl", "https://auth.company.com/api"}
};
Regex regEx = new Regex(@"\[(\w+)\]", RegexOptions.Compiled);
bool foundMatch = false;
strExpr = regEx.Replace(strExpr, match =>
{
string val = String.Empty;
if (variables.TryGetValue(match.Groups[1].Value, out val))
{
foundMatch = true;
return val;
}
return match.Value;
});
Match rmatch = regEx.Match(strExpr);
if (rmatch.Success && foundMatch )
{
return EvaluateStringWithVariables(strExpr);
}
return strExpr;
}
Related Topics
How to Calculate the Average Rgb Color Values of a Bitmap
Httpcontext.Current.Session Is Null in Ashx File
How to Get Text Between Nested Parentheses
Benefits of Using Async and Await Keywords
Using a List as a Data Source for Datagridview
How to Remove a Single Attribute (E.G. Readonly) from a File
Why Does the Linq Cast<> Helper Not Work with the Implicit Cast Operator
Getting the Index of a Particular Item in Array
How to Stop an Animation in C#/Wpf
Will Using Linq to SQL Help Prevent SQL Injection
How to Add the Same Column to All Entities in Ef Core
How to Set/Change/Remove Focus Style on a Button in C#
Programmatic Way to Get All the Available Languages (In Satellite Assemblies)