Home > OS >  Replacing a dictionary key in a string with the value
Replacing a dictionary key in a string with the value

Time:12-12

I'm currently trying to implement a changeAbbreviations function. I'm taking in messages from a .csv that are loaded into a textbox called txtContent. An example message would look like this:

"Hey just listened to your voicemail and I'm ROFL thanks for the jokes"

I have a dictionary that contains a list of textspeak abbreviations and their elongated values which I'm also reading in from a .csv which is structured like the below:

ROFL,Rolling on the floor laughing
LOL,Laughing out loud
AFK,Away from keyboard
BRB,Be right back
etc

What I'm trying to implement is that on a button click event the function will be called, replace the abbreviations with the elongated value and push the new message to a textbox called txtContentClean

The function will iterate through each word in a string and if a word matches one of the dictionary keys it will replace it with the value.

I'm not quite sure how to progress and was hoping someone might be able to show me how to implement this correctly. I've copied in my code so far below:

Dictionary:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

         Dictionary<string, string> dictionary = File.ReadAllLines("textwords.csv").Select(x => 
         x.Split(",", StringSplitOptions.RemoveEmptyEntries))
        .ToDictionary(key => key.FirstOrDefault().Trim(),
        value => value.Skip(1).FirstOrDefault().Trim());

changeAbbreviations Function:

       public void changeAbbreviations(string content, Dictionary<string, string> dictionary)
        {

            var abbreviations = new List<string>();
            foreach (string word in content.Split(' '))
            {
                bool wordExists = dictionary.ContainsKey(word);
                if (wordExists)
                {
                    abbreviations.Add(word);
                }
            }

            foreach (string word in abbreviations)
            {
                content.Replace(word, dictionary[word]);
            }

            txtContentClean.Text = content;
        }

Button Event:

        private void btnFilter_Click(object sender, RoutedEventArgs e)
        {
            changeAbbreviations();
        }

I hope I've setup this question correctly and thank you for any help :)

CodePudding user response:

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, @"\p{Lu} ", 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);
 }

CodePudding user response:

try this

string content="LOL you are funny";
content =  ChangeAbbreviations(content,dictionary);

result

Laughing out loud you are funny

code

public string ChangeAbbreviations(string content, Dictionary<string, string> dictionary)
{
    string pattern =@"[^0-9a-zA-Z:,] ";
    string[] strArray = Regex.Split(content, pattern,
                                  RegexOptions.IgnoreCase,
                                  TimeSpan.FromMilliseconds(500));

    for (var i=0; i < strArray.Length; i  )
      if ( dictionary.TryGetValue(strArray[i], out var wordFull)) 
                strArray[i] =  wordFull;
    
     return string.Join(" ", strArray);
}
  • Related