Regular Expression Needed

I would like a way to find all unique string that fit the following pattern:  
-----------------------------
[!output SomeText]
(the  SomeText part is, of course, any text string)
-----------------------------

For example i have a string like this:
-----------------------------
Hello [!output FullName],

Welcome to [!output Destination].  Please email us with any questions at [!output ContactEmail].  We hope you enjoy your stay at [!output Destination].

Sincerly,

[!output Signature]
-----------------------------
 I would like to get a list back of the distinct [!output ] tags.  For example, in this letter it would return a list something like this:

{[!output FullName], [!output Destination], [!output ContactEmail], [!output Signature]}

Or something like that, that will be easy to split after the values are returned.

Thanks for your help.
CaliguianAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

CaliguianAuthor Commented:
The following is what I came up with, but I am looking for a better way of doing it and I think that someone that is good with regular expressions might be able to come up with a better way:

protected SortableList GetReplacementNamesList(string inputString)
{
SortableList tags = new SortableList();
int startIndex = 0, endIndex = 0;
while((startIndex = inputString.IndexOf("[!output")) > -1)
{
      endIndex = inputString.IndexOf("]", startIndex)+1;
      string tag = inputString.Substring(startIndex,endIndex-startIndex);
      if(!tags.Contains(tag)) tags.Add(tag);
      inputString = inputString.Substring(endIndex);
}
return tags;
}
0
NipNFriar_TuckCommented:
Try this...

using System.Text.RegularExpressions;

string myString = "Hello [!output FullName],\r\n\r\n";
myString += "Welcome to [!output Destination].  Please email us with any questions at [!output ContactEmail].  We hope you enjoy your stay at [!output Destination].\r\n\r\n";
myString += "Sincerly, ";
Regex regex = new Regex(
    @"(\[\!output\s\w+])",
    RegexOptions.IgnoreCase
    | RegexOptions.Multiline
    | RegexOptions.IgnorePatternWhitespace
    | RegexOptions.Compiled
    );

MatchCollection matches= regex.Matches(myString);

// Now all matches are in the matches collection...
// access like:
for ( int i = 0; i < matches.Count; i++ ) {
   matches[i];
}

HTH
0
CaliguianAuthor Commented:
that looks good, but it doesn't seem to find all the matches.  For example, i passed in this string:

"Your action plan response was due <b><font color=\"red\">[!output AuditResult.FollowUpDueDate][!output AuditResult.FollowUpDueDate]</font></b> and is now <b><font color=\"red\">overdue</font></b> Follow the instructions below on how to provide your action plan response.<p />Response Format:<br><li>Access the action plan report by going <a href=\"http://madrid/WebApp/PlugIns/GeneralMills/SfActionPlan.aspx?id=[!output AuditResult.AuditResultGlobalID]&passcode=[!output FollowUpPasscode]\">here.</a></li><li>Use the unique passcode provided.</li></br>"

and it only reported one match, the [!output FollowUpPasscode].

Is there something missing?
0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

NipNFriar_TuckCommented:
That is due to the . the \w sais that it has to be alphanumeric...

Try this regex....

Regex regex = new Regex(
    @"(\[!output\s[A-Za-z0-9.]*\])",
    RegexOptions.IgnoreCase
    | RegexOptions.Multiline
    | RegexOptions.IgnorePatternWhitespace
    | RegexOptions.Compiled
    );

then if there are other special characters that you need to account for add them after the dot... depending on what they are you may have to escape them for instance if you want to look for a backslash "\" you would have to put in two backslashes (\\).
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
CaliguianAuthor Commented:
Great.  Thanks.  Actually the "." needed the backslash as well, but it works great.  thanks.
0
CaliguianAuthor Commented:
One more thing if your up for it; once i have the collection of matches, i would like to also get the value in between the [!output ] tags.  I still need the complete string (as your example above provided) but i would like to also be able to strip the tags off of a single match.  Any quick ideas on how to do that?
0
CaliguianAuthor Commented:
oh, this is not returning just the distincts, it is returning every instance.  any way to get just the distincts?
0
NipNFriar_TuckCommented:
To get the value is easy... just put another set of parens around the portions that you want...

Regex regex = new Regex(
    @"(\[!output\s([A-Za-z0-9\.]*)\])",
    RegexOptions.IgnoreCase
    | RegexOptions.Multiline
    | RegexOptions.IgnorePatternWhitespace
    | RegexOptions.Compiled
    );

MatchCollection matches = regex.Matches( myString );

Then I believe that you will access the matches to get the value you want like:
string aString = matches[0].Groups[2].Value;

As far as getting a unique list of the top of my head I would move what you want into another collection...

ArrayList alValues = new ArrayList();
foreach ( Match match in matches ) {
   if ( !alValues.Contains( match.Groups[2].Value ) ) {
      alValues.Add( match.Groups[2].Value);
   }
}

When you are done alValues will contain a uniques list of just the values inside the output tag... This may be able to be done with a custom IComparer on the collection also...

HTH
0
CaliguianAuthor Commented:
Thanks for the second regular expression.  I did end up moving the results to another collection to get the distincts.  Thanks for all your help.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.