1

I need to substitute all marked strings in a given string with some value, like:

"This is the level $levelnumber of the block $blocknumber."

I want to translate that to:

"This is the level 4 of the block 2."

This is just an example. In real I have several $data tags in text that needs to be changed at runtime to some data. I don´t know what $data tags will come in string.

I´m planning to use Regex for it, but regex is really confusing.

I´ve tried with no success this (with several variants of double quotes, no quote, etc.):

public static ShowTags (string Expression)
{
     var tags = Regex.Matches(Expression, @"(\$([\w\d]+)[&$]*");

     foreach (var item in tags)
          Console.WriteLine("Tag: " + item);
}

Any help appreciated.

[EDIT]

Working code:

public static ReplaceTagWithData(string Expression)
{ 
           string modifiedExpression;

            var tags = Regex.Matches(Expression, @"(\$[\w\d]+)[&$]*");

            foreach (string tag in tags)
            {
                /// Remove the '$'
                string tagname = pdata.Remove(0, 1);

                /// Change with current value
                modifiedExpression.Replace(pdata, new Random().ToString()); //Random simulate current value
            }

            return modifiedExpression;
}
Mendes
  • 17,489
  • 35
  • 150
  • 263
  • I guess you're looking for some templating library - http://stackoverflow.com/questions/340095/can-you-recommend-a-net-template-engine – Robert Oct 10 '13 at 19:23
  • Why not use string.Format? – Jonathan Nixon Oct 10 '13 at 19:29
  • 1
    Also this post may lead you in a direction as well. http://stackoverflow.com/questions/159017/named-string-formatting-in-c-sharp Using `String.Format` extensions to replace named parameters. – Khan Oct 10 '13 at 19:35
  • @Guthwulf Because it would be difficult to know whether to replace `{0}` or `{1}` with `levelnumber` without a long unbearable mapping. – Khan Oct 10 '13 at 19:39

3 Answers3

2

Try something like \$(?<key>[\w\d]+) instead. There are many regex testers out there, I suggest getting one of those to easily try out your regex.

Then, as Szymon suggested, you can use Regex.Replace, but there's a fancier way:

string result = Regex.Replace( s, pattern, new MatchEvaluator( Func ) );

string Func( Match m )
{
    return string.Format( "Test[{0}]", m.Groups["key"].Value );
}

Func above will be called once for every match it finds in the string allowing you to return a replacement string.

Chris
  • 5,442
  • 17
  • 30
1

You can use the code below to do the replacement for one tag.

 String tag = @"$levelnumber";
 String input = @"This is the level $levelnumber of the block $blocknumber.";
 string replacement = "4";

 String output = Regex.Replace(input, Regex.Escape(tag), replacement);

To do it in a loop for all tags (I used arrays of tags and replacements to simplify it):

 String input = @"This is the level $levelnumber of the block $blocknumber.";
 String[] tags = new String[] { "$levelnumber", "$blocknumber" };
 String[] replacements = new String[] { "4", "2" };

 for (int i = 0; i < tags.Length; i++)
     input = Regex.Replace(input, Regex.Escape(tags[i]), replacements[i]);

The end result is in input.

Note: you would achieve the same by using String.Replace:

input = input.Replace(tags[i], replacements[i]);

EDIT

Based on the comments below, you can use the following way. This will recocognize all tags starting with $ and replace them.

String input = @"This is the level $levelnumber of the block $blocknumber.";
Dictionary<string, string> replacements = new Dictionary<string,string>();
replacements.Add("$levelnumber", "4");
replacements.Add("$blocknumber", "2");

MatchCollection matches = Regex.Matches(input, @"\$\w*");
for (int i = 0; i < matches.Count; i++)
{
    string tag = matches[i].Value;
    if (replacements.ContainsKey(tag))
        input = input.Replace(tag, replacements[tag]);
}
Szymon
  • 42,577
  • 16
  • 96
  • 114
  • I don´t know in advance which tags are coming into string. So this does not work for me... – Mendes Oct 10 '13 at 21:45
  • You don't need to know in my solution. All you need is a tag and its replacement. – Szymon Oct 10 '13 at 21:52
  • "All you need is a tag and its replacement". Again: I have no tag in advance. The tag comes marked with $ in the string, then I will look on a dictionary if a replacement exists for the given tag. That´s why this doesn´t work for me... – Mendes Oct 15 '13 at 19:40
  • Sorry, couldn't get it at the start but please check my edit now, I think this is what you want. – Szymon Oct 15 '13 at 20:23
1

Consider the following to match the placeholders...

\$\w*

gpmurthy
  • 2,397
  • 19
  • 21