Solved

Complicated Message Translation Problem using C# and Regex

Posted on 2008-10-09
11
425 Views
Last Modified: 2009-07-29
Hi

This is quote a complex issue so feel free to ask any questions. I am at my wits end and have spent almost a week trying to resolve this so any help would be great. It is a lot to go through and I appreciate the time. If I could pay someone to help me with this I would, but unfortunately this site only works with points.

I need to convert a string message from one type (any format. E.g. EDIFACT) to another (any format E.g. XML).
To do this I setup a Message Type for each type, which consists of a number of Data Chunks.

1 Message Type -> many DataChunks


For example, I get the following message type (EDIFACT) string incoming:
----------------------------------
(A) Incoming Data Values
----------------------------------

UNH+00000149100001+CUSRES:D:96B:UN:ZZZ01'
BGM+962+2537'
BGM+962+2537+hello'
DTM+178:20080728:102'
LOC+22+CTN::ZZZ'
GIS+8:120:ZZZ'
UCM+00000956300002+CUSDEC:D:96B:UN:ZZZ01+4'
UCS+21'
UCD+14+3:6'
UCM+00000956300001+CUSDEC:D:96B:UN:ZZZ01+4'
UCS+21'
UCD+14+3:6'
DTM+137:20080728:102'


And I have the following Template Setup for this expected incoming String:
(Note that you can almost juxtapose the template below on top of the values, although there are a couple of discrepancies which I will explain further down)
------------------------------------
(B) Incoming Data Template
------------------------------------

UNH+{MessageReferenceNumber}+{MessageType}:{MessageVersionNumber}:{MessageReleaseNumber}:{ControllingAgency}:{AssociationAssignedCode}'
BGM+{DocumentMessageName}+{DocumentMessageId}'
BGM+{DocumentMessageName}+{DocumentMessageId}+{MessageFunctionCoded}'
DTM+{DateTimePeriodQualifier}:{DateTimePeriod}:{DateTimePeriodFormatQualifier}'
LOC+{PlaceLocationQualifier}+{PlaceLocationIdentification}:{CodeListQualifier}:{CodeListResponsibleAgency}'
GIS+{ProcessingIndicator}:{CodeListQualifier}:{CodeListResponsibleAgency}'
UCM+{UcmName}+{UcmDescription}:{UcmCode}:{UcmReference}:{UcmCountry}:{UcmCurrency}+{UcmDelimiter}'
UCS+{UcmHeader}'
UCD+{UcmDetail}+{UcmSummary}:{UcmTotal}'
NAD+{PartyQualifier}+{PartyIdentificationDetails}'
DTM+{DateTimePeriodQualifier}:{DateTimePeriod}:{DateTimePeriodFormatQualifier}'


And I have the following Template Setup for the desired outgoing String:
-----------------------------------------
(C) Outgoing Data Template
-----------------------------------------

<UNH MessageReferenceNumber="{MessageReferenceNumber}" MessageType={MessageType} MessageVersionNumber="{MessageVersionNumber}" MessageReleaseNumber="{MessageReleaseNumber}" ControllingAgency="{ControllingAgency}" AssociationAssignedCode="{AssociationAssignedCode}" />
<BGM documentMessageName="{DocumentMessageName}" documentMessageId="{DocumentMessageId}" />
<BGM documentMessageName="{DocumentMessageName}" documentMessageId="{DocumentMessageId}" messageFunctionCoded="{MessageFunctionCoded}" />
<DTM dateTimePeriodQualifier="{DateTimePeriodQualifier}" DateTimePeriod="{DateTimePeriod}" DateTimePeriodFormatQualifier="{DateTimePeriodFormatQualifier}" />
<LOC placeLocationQualifier={PlaceLocationQualifier} placeLocationIdentification={PlaceLocationIdentification} codeListQualifier={CodeListQualifier} codeListResponsibleAgency={CodeListResponsibleAgency} />
<GIS processingIndicator={ProcessingIndicator} codeListQualifier={CodeListQualifier} codeListResponsibleAgency={CodeListResponsibleAgency} />
<UCM UcmName="{UcmName}" UcmDescription="{UcmDescription}" UcmCode="{UcmCode}" UcmReference="{UcmReference}" UcmCountry="{UcmCountry}" UcmCurrency="{UcmCurrency}" UcmDelimiter="{UcmDelimiter}" />
<UCS UcmHeader="{UcmHeader}" />
<UCD UcmDetail="{UcmDetail}" UcmSummary="{UcmSummary}" UcmTotal="{UcmTotal}" />
<DTM dateTimePeriodQualifier="{DateTimePeriodQualifier}" DateTimePeriod="{DateTimePeriod}" DateTimePeriodFormatQualifier="{DateTimePeriodFormatQualifier}" />


So from these templates, you can see that I need to compare the Input String (A) against the Input template (B) and based on any values found created a Dictionary of data that will be used to populate the Output template variables in (C).

For example, if you look at the first Data Chunk in (A), (line 1 beginning with UNH), I will compare input A and template B and get a dictionary of values like this:
[MessageReferenceNumber][00000149100001]
[MessageType][CUSRES]
[MessageVersionNumber][D]
[MessageReleaseNumber][96B]
[ControllingAgency][UN]
[AssociationAssignedCode][ZZZ01]

Note now that in Template C I have placeholders with the same variable name as the key in the dictionary above, so I need to search for the key in template C and simply replace the (for example) {MessageReferenceNumber} with 00000149100001.


Thanks to the help of the generous people on these forums, I managed to get a solution up and running that accomplished all this, using Regular Expressions. But since then, the requirements have changed which has just blown that whole solution to smithereens.


What is a Data Chunk?
A Data Chunk is simply a section of text within the message and message templates, and can consist of one or more lines, depending totally on how the user sets it up. The following examples below illustrate what a Data chunk could look like:
------------------------------------------------
(D1) DATA CHUNK EXAMPLE 1
------------------------------------------------

(The Values in the Data Chunk)
UNH+00000149100001+CUSRES:D:96B:UN:ZZZ01'    

(The template of the incoming DataChunk)
UNH+{MessageReferenceNumber}+{MessageType}:{MessageVersionNumber}:{MessageReleaseNumber}:{ControllingAgency}:{AssociationAssignedCode}'      

(The template of the incoming DataChunk)
<UNH MessageReferenceNumber="{MessageReferenceNumber}" MessageType={MessageType} MessageVersionNumber="{MessageVersionNumber}" MessageReleaseNumber="{MessageReleaseNumber}" ControllingAgency="{ControllingAgency}" AssociationAssignedCode="{AssociationAssignedCode}" />      (The template of the incoming DataChunk)


ALSO, if you look at Template (B) again, note that the following three lines could also be considered ONE data chunk  again  its all up to the user setting up the data chunk:
------------------------------------------------
(D2) DATA CHUNK EXAMPLE 2
------------------------------------------------


UCM+{UcmName}+{UcmDescription}:{UcmCode}:{UcmReference}:{UcmCountry}:{UcmCurrency}+{UcmDelimiter}'
UCS+{UcmHeader}'
UCD+{UcmDetail}+{UcmSummary}:{UcmTotal}'


The Problems:

Each Data Chunk in the Incoming and Outgoing templates, can now have certain properties that need to be taken into consideration when matching the values to the template. These are setup when the user creates the data chunk.
These are:
"      Is the Data Chunk repeatable?
If you compare the Data Chunk illustrated in D2 against the values in A, you will see that the DataChunk pattern repeats twice. This is an example of a repeatable data chunk. The repeated data will always be sequential  in other words you wont find an instance of one data chunk and then another 10 lines down. It is possible, but that is not a repeatable data chunk, just another instance of it.
"      Can the Data Chunk be omitted?
This simply means when you are validating the values in template A against the template B and a DataChunk In B is marked as required, then if it is not found an error should be thrown. For example, in template B, the second last line is a Data Chunk beginning with NAD. However in template A, there is no value for that Data Chunk. This would error if the Data Chunk was set as required else it would just ignore that DataChunk and not error and move onto the next DataChunk. This flag simply determines whether to error or not if that data chunk in template B was expected and not found.
"      Are all fields in the Data Chunk required?
Given the Data Chunk from template B: BGM+{DocumentMessageName}+{DocumentMessageId}+{MessageFunctionCoded}'
And the data in is: BGM+test+1234
If this flag is set to true, then an error must be thrown as the last value was not supplied for MessageFunctionCoded. But if it is set to false, then not all fields are required, and only the matched values for that data chunk need to be replaced.


PHEW!!!

So with that all explained, I now somehow need to find a solution here.


How I envision this happening  and I could be totally off here, is:
"      build a dictionary of keys and values based on a comparison between template A and B, taking the data chunk properties into account (i.e. Repeatable? / Can be Omitted? / All Fields required)
"      Populate template C with the values from the dictionary where the dictionarys key value matches the same key in Template C

Please help!!!! :)

I can provide the old code which did this. It did not however take the new Data Chunk properties into consideration. It simply took the values in A based on template B, and populated it into template C. This only worked when the message structure of A matched that of B exactly. The problem now is that it needs to take repeatable data chunks, omitted data chunks and data chunks with fields missing into consideration!!

So many thanks in advance.
0
Comment
Question by:djcheeky
  • 6
  • 5
11 Comments
 
LVL 27

Expert Comment

by:ddrudik
Comment Utility
djcheeky, I likely can't answer your entire question with one post, but hopefully the process outlined in the code below will help you get started.  It takes your incoming tempalate and creates regex patters from each line, then matches each line of your incoming data with each of the regex patterns, performing the replacments in an output string based on the output template.
using System;

using System.Text.RegularExpressions;

namespace retest

{

    class Program

    {

        static void Main(string[] args)

        {

            string incoming = @"UNH+00000149100001+CUSRES:D:96B:UN:ZZZ01'

BGM+962+2537'

BGM+962+2537+hello'

DTM+178:20080728:102'

LOC+22+CTN::ZZZ'

GIS+8:120:ZZZ'

UCM+00000956300002+CUSDEC:D:96B:UN:ZZZ01+4'

UCS+21'

UCD+14+3:6'

UCM+00000956300001+CUSDEC:D:96B:UN:ZZZ01+4'

UCS+21'

UCD+14+3:6'

DTM+137:20080728:102'";

            string incomingTemplate = @"UNH+{MessageReferenceNumber}+{MessageType}:{MessageVersionNumber}:{MessageReleaseNumber}:{ControllingAgency}:{AssociationAssignedCode}'

BGM+{DocumentMessageName}+{DocumentMessageId}'

BGM+{DocumentMessageName}+{DocumentMessageId}+{MessageFunctionCoded}'

DTM+{DateTimePeriodQualifier}:{DateTimePeriod}:{DateTimePeriodFormatQualifier}'

LOC+{PlaceLocationQualifier}+{PlaceLocationIdentification}:{CodeListQualifier}:{CodeListResponsibleAgency}'

GIS+{ProcessingIndicator}:{CodeListQualifier}:{CodeListResponsibleAgency}'

UCM+{UcmName}+{UcmDescription}:{UcmCode}:{UcmReference}:{UcmCountry}:{UcmCurrency}+{UcmDelimiter}'

UCS+{UcmHeader}'

UCD+{UcmDetail}+{UcmSummary}:{UcmTotal}'

NAD+{PartyQualifier}+{PartyIdentificationDetails}'";

            string outgoingTemplate = @"<UNH MessageReferenceNumber=""{MessageReferenceNumber}"" MessageType={MessageType} MessageVersionNumber=""{MessageVersionNumber}"" MessageReleaseNumber=""{MessageReleaseNumber}"" ControllingAgency=""{ControllingAgency}"" AssociationAssignedCode=""{AssociationAssignedCode}"" />

<BGM documentMessageName=""{DocumentMessageName}"" documentMessageId=""{DocumentMessageId}"" />

<BGM documentMessageName=""{DocumentMessageName}"" documentMessageId=""{DocumentMessageId}"" messageFunctionCoded=""{MessageFunctionCoded}"" />

<DTM dateTimePeriodQualifier=""{DateTimePeriodQualifier}"" DateTimePeriod=""{DateTimePeriod}"" DateTimePeriodFormatQualifier=""{DateTimePeriodFormatQualifier}"" />

<LOC placeLocationQualifier={PlaceLocationQualifier} placeLocationIdentification={PlaceLocationIdentification} codeListQualifier={CodeListQualifier} codeListResponsibleAgency={CodeListResponsibleAgency} />

<GIS processingIndicator={ProcessingIndicator} codeListQualifier={CodeListQualifier} codeListResponsibleAgency={CodeListResponsibleAgency} />

<UCM UcmName=""{UcmName}"" UcmDescription=""{UcmDescription}"" UcmCode=""{UcmCode}"" UcmReference=""{UcmReference}"" UcmCountry=""{UcmCountry}"" UcmCurrency=""{UcmCurrency}"" UcmDelimiter=""{UcmDelimiter}"" />

<UCS UcmHeader=""{UcmHeader}"" />

<UCD UcmDetail=""{UcmDetail}"" UcmSummary=""{UcmSummary}"" UcmTotal=""{UcmTotal}"" />

<DTM dateTimePeriodQualifier=""{DateTimePeriodQualifier}"" DateTimePeriod=""{DateTimePeriod}"" DateTimePeriodFormatQualifier=""{DateTimePeriodFormatQualifier}"" />";

            string regexpatterns = Regex.Replace(Regex.Replace(Regex.Replace(incomingTemplate, @"\+", @"\+"), @"\{", @"(?<"), @"\}", @">.*?)");

            Regex reLines = new Regex("\r\n");

            String[] lines = reLines.Split(incoming);

            String[] patterns = reLines.Split(regexpatterns);

            String outputString = outgoingTemplate;

            for (int lineIdx = 0; lineIdx < lines.Length; lineIdx++)

            {

                Console.WriteLine("\r\nLINE: " + lines[lineIdx]);

                for (int pIdx = 0; pIdx < patterns.Length; pIdx++)

                {

                    string pattern = @"^" + patterns[pIdx] + @"$";

                    Regex reParse = new Regex(pattern);

                    if(reParse.IsMatch(lines[lineIdx]))

                    {

                        Console.WriteLine("PATTERN: " + pattern);

                        Match m = reParse.Match(lines[lineIdx]);

                        for (int gIdx = 1; gIdx < m.Groups.Count; gIdx++)

                        {

                            Console.WriteLine("[" + reParse.GetGroupNames()[gIdx] + "] = " + m.Groups[gIdx].Value);

                            outputString = Regex.Replace(outputString, @"\{" + reParse.GetGroupNames()[gIdx] + @"\}", m.Groups[gIdx].Value);

                        }

                    }
 

                }

            }

            Console.WriteLine("\r\noutputString:\r\n" + outputString);

        }

    }

}

Open in new window

0
 

Author Comment

by:djcheeky
Comment Utility
Hi ddrudik

Thanks

I think what I am going to try and do then, is handle the extraction of the input variables from the input by going through both the input template and input string ONE Data Chunk at a time, sequentially.

I will then use regular expressions to try and match each data chunk template e.g.
UNH+{MessageReferenceNumber}+{MessageType}:{MessageVersionNumber}:{MessageReleaseNumber}:{ControllingAgency}:{AssociationAssignedCode}'

with the next value in the input string e.g.
UNH+00000149100001+CUSRES:D:96B:UN:ZZZ01'

I can then also implement my rules on a Data Chunk level, so that if the regular expression does not find a value match for the template, I can throw my "Data Chunk is required but not found" error. I can also do the same for repeatable data chunks and data chunks that permit certain fields to be ommitted.

So I am going to get started on that function, but will def need some help with the regular expression portion of it, so when I get there (either today or monday) I will specify what part of this problem exactly I need assistance with.

The good thing is that I am starting to grasp some of these regular expressions now after looking at them repeatedly, which is a good thing :)

Chat soon and thanks!

0
 

Author Comment

by:djcheeky
Comment Utility
Hi ddrudik.

Ok, I have managed to get somewhere and have hit the first stumbling block:

Given the original data and templates listed in A, B and C, I have written the function listed below.

What it currently does is loop through each data chunk (item) in Template B and then creates a Regular Expression based on that template.

Then what it does is it tries to match that regular expression against the incoming data (A) to find a match. Now when it tries to do the match, it throws the exception because it is comparing the regular expression that i created for ONE line against the WHOLE message_IN template (A) and naturally they don't match as A is a whole body of text.

What I am actually trying to do is check whether the regular expression generated matches the first item of text in the message_IN template (A). e.g.

Do I find text matching the template:
UNH+{MessageReferenceNumber}+{MessageType}:{MessageVersionNumber}:{MessageReleaseNumber}:{ControllingAgency}:{AssociationAssignedCode}'

in the top section of the message_IN input in A, being:
UNH+00000149100001+CUSRES:D:96B:UN:ZZZ01'

If I do, then I would like to extract the values, then remove the first instance of the matched Regex text, being:
UNH+00000149100001+CUSRES:D:96B:UN:ZZZ01'
from the message_IN template.

Therefore, if I started with message_IN being:
UNH+00000149100001+CUSRES:D:96B:UN:ZZZ01'    //this is the match to find and then remove from message_IN
BGM+962+2537'
BGM+962+2537+hello'
DTM+178:20080728:102'

it would now be:
BGM+962+2537'
BGM+962+2537+hello'
DTM+178:20080728:102'

Now, as stated, I can see how to match the Regex pattern against the WHOLE of message_IN, which is wrong though. What I need to do is see if the Regex pattern matches with the first match of its related value in message_IN, and if so delete that occurance of the match's value from message_IN.

I hope I am explaining myself correctly - if not  just ask.
I really appreciate the help.
I think after this i will close the question, and post each seperate, but related question in a seperate question to make the awarding of points more fair so that you get points for each question and not one set of points for all questions.

Thanks, Paolo








private Dictionary<String, String> GetMessageInDictionary(String message_IN, List<MessageTypeToDataChunk> messageTypeToDataChunks_IN)

		{

			Dictionary<String, String> messageInDictionary;

			Regex reg;

			List<String> keys;

			String template;

			String pattern;

			String keyName, keyValue;

			int index;

			String lastMatch = "";

			

			//Init

			messageInDictionary = new Dictionary<string, string>();

			reg = new Regex("(?<text>[^{}]*)({(?<key>[^}]+)})?"); // .NET Regular Expression matching KeyTemplate Grammar

			keys = new List<string>();

							

			//Find the first match between each DataChunk and the Data

			foreach (MessageTypeToDataChunk messageTypeToDataChunk in messageTypeToDataChunks_IN)

			{

				template = messageTypeToDataChunk.dataChunk.dataChunkBody;

				

				//Preconditions : Check if the given Data Chunk template conforms to the KeyTemplate syntax

				if (!reg.IsMatch(template))

				{

					throw new Exception("Invalid Message IN Template Encountered. Data Chunk does not conform to the expected structure.");

				}

				

				//Template Translator : Translates the KeyTemplate into a .NET Regular Expression that will match the KeyValue

				pattern = "^";

				foreach (Match match in reg.Matches(template))

				{

					// Handle whitespaces in the Values

					keyValue = "";

					foreach (char c in match.Groups["text"].Value)

					{

						if (c != ' ' && c != '\t')

							keyValue += c + "$$SPACE$$";

						else

							keyValue += c;

					}

					keyValue = keyValue.Replace("$$SPACE$$ ", "$$SPACE$$");
 

					//  Remove the last white space matcher of the pattern

					if (keyValue.EndsWith("$$SPACE$$"))

						keyValue = keyValue.Substring(0, keyValue.Length - "$$SPACE$$".Length);
 

					pattern += keyValue.Replace("+", "\\+").Replace(".", "\\.").Replace("*", "\\*").Replace("?", "\\?").Replace("(", "\\(").Replace("[", "\\[").Replace("]", "\\]").Replace(")", "\\)").Replace("$$SPACE$$", "\\s*");
 

					if (match.Groups["key"].Value != "")

					{

						keyName = match.Groups["key"].Value.Replace("+", "\\+").Replace(".", "\\.").Replace("*", "\\*").Replace("?", "\\?").Replace("(", "\\(").Replace("[", "\\[").Replace("]", "\\]").Replace(")", "\\)");

						

						// Generate a valid key name for the result dictionary to avoid duplicates when repeating the template

						if (keys.Contains(keyName))

						{

							index = 1;

							while (keys.Contains(keyName + "_" + index.ToString())) index++;

							keyName = keyName + "_" + index.ToString();

						}

						keys.Add(keyName);

						

						//A value may be omitted so make its matcher optional

						pattern += string.Format("(?<{0}>.*)", keyName);

						lastMatch = keyName;

					}
 

				}

				pattern += "$";
 

				//messageInDictionary.Add(lastMatch, pattern);
 

				//Value Extractor : Uses the generated Regex to extract values from the input

				reg = new Regex(pattern);

				if (!reg.IsMatch(message_IN))

				{

					throw new Exception("The Message IN Message Structure differs from that of the Message IN Template Structure and thus a conversion can not be done between the two. Last Successful Match Key was: " + lastMatch);

				}
 

			}

			return messageInDictionary;		

			

		}

	}

Open in new window

0
 
LVL 27

Expert Comment

by:ddrudik
Comment Utility
If you want to match the first line of the source string with the first regex pattern, I would simply split the patterns and source string on \r\n as I did in my code and then loop through the matchcollection of each, comparing each line to it's corresponding regex.  Not sure if that's what you are asking though.
0
 

Author Comment

by:djcheeky
Comment Utility
You are correct, however the pattern and data could span multiple lines and contain \r\n , so you can't rely on that as the delimiter.

e.g.

Template Block:

UCM+{UcmName}+{UcmDescription}:{UcmCode}:{UcmReference}:{UcmCountry}:{UcmCurrency}+{UcmDelimiter}'
UCS+{UcmHeader}'
UCD+{UcmDetail}+{UcmSummary}:{UcmTotal}'

Data Block:

UCM+00000956300002+CUSDEC:D:96B:UN:ZZZ01+4'
UCS+21'
UCD+14+3:6'

Is it possible to match that whole block, including the newlines \ carriage returns?

What I am aiming for is:
* looping through each template block which may be one line or more (as above)
* creating a regex that matches that pattern for that template block
* applying that pattern to the data values, so if the template block pattern spans 3 lines, then it must try find the same in the values.

Thanks

0
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

 
LVL 27

Accepted Solution

by:
ddrudik earned 500 total points
Comment Utility
Consider this example:
using System;

using System.Text.RegularExpressions;

namespace retest

{

    class Program

    {

        static void Main(string[] args)

        {

            string incoming = @"UCM+00000956300002+CUSDEC:D:96B:UN:ZZZ01+4'

UCS+21'

UCD+14+3:6'";

            string incomingTemplate = @"UCM+{UcmName}+{UcmDescription}:{UcmCode}:{UcmReference}:{UcmCountry}:{UcmCurrency}+{UcmDelimiter}'

UCS+{UcmHeader}'

UCD+{UcmDetail}+{UcmSummary}:{UcmTotal}'";

            string repattern = Regex.Replace(Regex.Replace(Regex.Replace(incomingTemplate, @"\+", @"\+"), @"\{", @"(?<"), @"\}", @">.*?)");

            Regex reParse = new Regex(repattern);

            if (reParse.IsMatch(incoming))

            {

                Match m = reParse.Match(incoming);

                for (int gIdx = 1; gIdx < m.Groups.Count; gIdx++)

                {

                    Console.WriteLine("[" + reParse.GetGroupNames()[gIdx] + "] = " + m.Groups[gIdx].Value);

                }

            }

        }

    }

}

Open in new window

0
 

Author Comment

by:djcheeky
Comment Utility
Thanks ddrudik, that is pretty much exactly what I wanted. Just one small thing I noticed when I changed the incoming data and template somewhat. If you look at the code, you'll see I added another element to the template and value. The only difference is that I left out the terminating character, a single quote ( ' ) from the last item, and when the data displays it goes a bit wonky and shows:

(only the last two entries show here to illustrate the issue)

[var1] = 1
[var2] =

But if I then add the single quote, it works correctly, displaying:

[var1] = 1
[var2] = 2

Why is this? It should work fine if it's just matching patterns and I have looked in the Regex code and don't find anything referencing the single quote ( ' )
Any ideas?


static public void translateMessage()

        {

            string incoming = @"UCM+00000956300002+CUSDEC:D:96B:UN:ZZZ01+4'

UCS+21'

UCD+14+3:6'

NAME+1+2";

            string incomingTemplate = @"UCM+{UcmName}+{UcmDescription}:{UcmCode}:{UcmReference}:{UcmCountry}:{UcmCurrency}+{UcmDelimiter}'

UCS+{UcmHeader}'

UCD+{UcmDetail}+{UcmSummary}:{UcmTotal}'

NAME+{var1}+{var2}";

            string repattern = Regex.Replace(Regex.Replace(Regex.Replace(incomingTemplate, @"\+", @"\+"), @"\{", @"(?<"), @"\}", @">.*?)");

            Regex reParse = new Regex(repattern);

            if (reParse.IsMatch(incoming))

            {

                Match m = reParse.Match(incoming);

                for (int gIdx = 1; gIdx < m.Groups.Count; gIdx++)

                {

                    Console.WriteLine("[" + reParse.GetGroupNames()[gIdx] + "] = " + m.Groups[gIdx].Value);

                }

            }

            Console.ReadKey();

        }

Open in new window

0
 

Author Comment

by:djcheeky
Comment Utility
Hi again ddrudik - I have found a couple of other issues as well, but I am going to put them into a seperate thread, so keep an eye out for them, as I will be using the same code from this example to illustrate the issue :)     Thanks.
0
 
LVL 27

Expert Comment

by:ddrudik
Comment Utility
I forgot to add the ^ and $ to the pattern:
            string repattern = "^" + Regex.Replace(Regex.Replace(Regex.Replace(incomingTemplate, @"\+", @"\+"), @"\{", @"(?<"), @"\}", @">.*?)") + "$";
0
 

Author Comment

by:djcheeky
Comment Utility
Thanks ddrudik, that did the trick.
I really appreciate your help - this last question really helped me with regular expressions and I am slowly but surely getting there. This last week has def been a crash course in Regular Expressions for me.
0
 
LVL 27

Expert Comment

by:ddrudik
Comment Utility
Thanks for the question and the points.
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Okay. So what exactly is the problem here? How often have we come across situations where we need to know if two strings are 'similar' but not necessarily the same? I have, plenty of times. Until recently, I thought any functionality like that wo…
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!
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

11 Experts available now in Live!

Get 1:1 Help Now