C# String Replace with Dictionary

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



Leave a reply



Submit