Solved

Replacing Values in a String with values from a Dictionary

Posted on 2008-10-03
6
1,574 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
6 Comments
 
LVL 27

Accepted Solution

by:
ddrudik earned 500 total points
ID: 22639830
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
ID: 22649038
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
ID: 22650466
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
[Live Webinar] The Cloud Skills Gap

As Cloud technologies come of age, business leaders grapple with the impact it has on their team's skills and the gap associated with the use of a cloud platform.

Join experts from 451 Research and Concerto Cloud Services on July 27th where we will examine fact and fiction.

 
LVL 27

Expert Comment

by:ddrudik
ID: 22650516
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
ID: 22650638
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
ID: 22650653
Glad I could help.  Thanks for the question and the points.
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Summary: Persistence is the capability of an application to store the state of objects and recover it when necessary. This article compares the two common types of serialization in aspects of data access, readability, and runtime cost. A ready-to…
This article introduced a TextBox that supports transparent background.   Introduction TextBox is the most widely used control component in GUI design. Most GUI controls do not support transparent background and more or less do not have the…
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…

632 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