Solved

Replacing Values in a String with values from a Dictionary

Posted on 2008-10-03
6
1,552 Views
Last Modified: 2012-05-05
Hi all.

In a previous thread, I needed to extract values from a String into a dictionary based on a template string provided. (See: http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_23774171.html?cid=239#a22614648)

Both solutions provided by CuteBug and Sandson worked perfectly. But now I need to do the same sort of thing, but in reverse. What I need to do is  replace values in a Template with values  from a dictionary i.e.:

Given the Dictionary Values:

[DocumentMessageName][962]
[DocumentMessageId][2537]
[PartyQualifier][AG]
[PartyIdentificationDetails][00047178]
[DocumentMessageName_1][12]
[DocumentMessageId_1][345]
[DocumentMessageDetail][678910]

Given the templates:

(1)
BGM+{DocumentMessageName}_{DocumentMessageId}'
NAD+{PartyQualifier}+{PartyIdentificationDetails}'
BGM+{DocumentMessageName}_{DocumentMessageId}^{DocumentMessageDetail}'

(2)
<BGM documentMessageName={DocumentMessageName} documentMessageId={DocumentMessageId} />
<NAD partyQualifier={PartyQualifier} partyIdentificationDetails={PartyIdentificationDetails} />
<BGM documentMessageName={DocumentMessageName} documentMessageId={DocumentMessageId} documentMessageDetail="{documentMessageDetail}" />


The result should be:

(1)
BGM+962_2537'    
NAD+AG+00047178'
BGM+12_345^678910'

(2)
<BGM documentMessageName=962 documentMessageId=2537 />
<NAD partyQualifier=AG partyIdentificationDetails=00047178 />
<BGM documentMessageName=12 documentMessageId=345 documentMessageDetail="678910" />


As you can see in the templates above, if there is a duplicate Dictionary Key, the variable name simply gets a "_1" or "_2" or "_amountOfTimesVarNameOccurs" before it was added to the Dictionary.
This means that as you are replacing the values in the template, the first occurance of a key is replaced with "thevariableName", the second with "theVariableName_1", the third with "theVariableName_2" etc.

This can be seen for the BGM DocumentMessageName and DocumentMessageId keys, but not the DocumentMessageDetail as it only occurs once.

The Code has to be flexible enough so that it can replace any instance of {aVariableName} in a tempate with the corresponding key's value in the Dictionary.

Now I have scratched my head over this and must admit when it comes to Regular expressions, which is one of the ways the previous thread I mentioned was used to solve this, I'm a total dummy but am trying to get there :)

If anyone could assist, even Sandson or Cutebug from yesterday, that would be great!!

Thanks
Paolo





0
Comment
Question by:djcheeky
  • 4
  • 2
6 Comments
 
LVL 27

Accepted Solution

by:
ddrudik earned 500 total points
Comment Utility
Consider the following code (note that in your source text you had a case typo 'documentMessageDetail="{documentMessageDetail}" ' should have read 'documentMessageDetail="{DocumentMessageDetail}" ' that I corrected in the source text below):
using System;

using System.Collections;

using System.Collections.Generic;

using System.Text.RegularExpressions;

namespace ReNameSpace

{

    class ReClass

    {

        public static Regex re = new Regex(@"\{([^}]*)\}");

        public static ArrayList keysAL = new ArrayList();

        public static ArrayList countsAL = new ArrayList();

        public static Dictionary<string, string> myDictionary = new Dictionary<string, string>();

        static string newVal(Match m)

        {

            string key = m.Groups[1].Value;

            if (keysAL.Contains(key))

            {

                int ind = keysAL.IndexOf(key);

                int count = (int)countsAL[ind];

                count++;

                key = key + "_" + count;

                countsAL[ind] = count;

            }

            else

            {

                keysAL.Add(key);

                countsAL.Add(0);

            }

            string value = "";

            if (myDictionary.TryGetValue(key, out value))

            {

                return value;

            }

            else

            {

                return "<<" + key + " not found>>";

            }

        }

        static string repKeys(string input)

        {

            keysAL = new ArrayList();

            countsAL = new ArrayList();

            return re.Replace(input, new MatchEvaluator(ReClass.newVal));

        }

        public static void Main(string[] args)

        {

            myDictionary.Add("DocumentMessageName", "962");

            myDictionary.Add("DocumentMessageId", "2537");

            myDictionary.Add("PartyQualifier", "AG");

            myDictionary.Add("PartyIdentificationDetails", "00047178");

            myDictionary.Add("DocumentMessageName_1", "12");

            myDictionary.Add("DocumentMessageId_1", "345");

            myDictionary.Add("DocumentMessageDetail", "678910");

            Console.WriteLine(repKeys(@"BGM+{DocumentMessageName}_{DocumentMessageId}'

NAD+{PartyQualifier}+{PartyIdentificationDetails}'

BGM+{DocumentMessageName}_{DocumentMessageId}^{DocumentMessageDetail}'"));

            Console.WriteLine();

            Console.WriteLine(repKeys(@"<BGM documentMessageName={DocumentMessageName} documentMessageId={DocumentMessageId} />

<NAD partyQualifier={PartyQualifier} partyIdentificationDetails={PartyIdentificationDetails} />

<BGM documentMessageName={DocumentMessageName} documentMessageId={DocumentMessageId} documentMessageDetail=""{DocumentMessageDetail}"" />"));

        }

    }

}

Open in new window

0
 

Author Comment

by:djcheeky
Comment Utility
Hi

Thanks - this works great.

Would it be possible for you to comment what is actually happening as I am trying to learn Regular Expressions but find them extremely difficult and intimidating and would love to actually learn what is going on in this code?

Thanks
Paolo
0
 
LVL 27

Expert Comment

by:ddrudik
Comment Utility
Just a bit of the code is regex-related, but here's that:
        public static Regex re = new Regex(@"\{([^}]*)\}");
The above pattern matches anything between { } and captures that to Groups[1] of each match.
            return re.Replace(input, new MatchEvaluator(ReClass.newVal));
The above line performs the replacement, but instead of a plain string replacement it uses a MatchEvaluator defined as newVal, which since I am more familiar with PHP I will compare it to PHP's preg_replace_callback function.  A function (in this case newVal) is applied to each match before replacement, allowing for greater flexibility in the replacements returned.

The rest is non-regex code, the ArrayLists are used to increment the matched string variable names as you have them in your Dictionary example.

Here's the regex pattern explanation:
NODE                     EXPLANATION

----------------------------------------------------------------------

  \{                       '{'

----------------------------------------------------------------------

  (                        group and capture to \1:

----------------------------------------------------------------------

    [^}]*                    any character except: '}' (0 or more

                             times (matching the most amount

                             possible))

----------------------------------------------------------------------

  )                        end of \1

----------------------------------------------------------------------

  \}                       '}'

----------------------------------------------------------------------

Open in new window

0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 27

Expert Comment

by:ddrudik
Comment Utility
For an online regex tester you might give my site a try:
http://www.myregextester.com

The four icons in the upper right corner of the site are links to other regex resources that might be of interest to you, including a good tutorial site and an excellent book on the subject, "Mastering Regular Expressions" by Friedl.
0
 

Author Comment

by:djcheeky
Comment Utility
Cool - Thanks a million. I will definitely be sharpening my RegEx skills over the next few weeks. It's amazing how powerful they actually are.

Keep an eye out for another question from me within the next day or two about Regular Expressions :)

Ta.
0
 
LVL 27

Expert Comment

by:ddrudik
Comment Utility
Glad I could help.  Thanks for the question and the points.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now