2

Given a file with this format

// Colour
$primary-colour: if(@Model.PrimaryColour, @primaryColour, #afd05c);
$secondary-colour: if(@secondaryColour, @secondaryColour, #323f47);
// and so on

I'm trying to replace the @Model.Whatever based on a dictionary with would be something like this

var dictionary = new Dictionary<string, string>
{
    {"primaryColour", "blue"},
    {"secondaryColour", "red"}
};

But I'm struggling to find a way to so.

I was thinking of doing something like this:

private static String Replace(String str)
{
    var dictionary = new Dictionary<string, string>
    {
        {"primaryColour", "blue"},
        {"secondaryColour", "red"}
    };

    string variableValue;
    string pattern = @"@Model.(?<name>\w)";
    dictionary.TryGetValue(FirstCharacterToLower("${name}"), out variableValue);
    var replacePattern = String.Format("{0}", variableValue);
    return Regex.Replace(str, pattern, replacePattern, RegexOptions.IgnoreCase);
}

private static string FirstCharacterToLower(string str)
{
    Console.WriteLine(str);
    if (String.IsNullOrEmpty(str) || Char.IsLower(str, 0))
        return str;

    return Char.ToLowerInvariant(str[0]) + str.Substring(1);
}

But what I'm passing to the FirstCharacterToLower is just a string {name} and I'm stuck there. Can't think of a way to do it.

Any idea where to go from here?

Thanks

Edit: Based on sln comment I made this and it works

using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {

        var input = @"
            // Colour
            $primary-colour: if(@Model.PrimaryColour, @Model.PrimaryColour, #afd05c);
            $secondary-colour: if(@Model.SecondaryColour, @Model.SecondaryColour, #323f47);";

        Console.WriteLine(Replace(input));
    }

    private static String Replace(String str)
    {
        var dictionary = new Dictionary<string, string>
        {
            {"primaryColour", "blue"},
            {"secondaryColour", "red"}
        };

        var regex = new Regex(@"@Model\.(?<name>\w+)");

        var output = regex.Replace(str, v => 
            {
                string outVariable;
                dictionary.TryGetValue(GetNameOfVariable(v.Groups["name"].Value), out outVariable);
                return outVariable;
            });

        return output;
    }

    private static string GetNameOfVariable(string str)
    {
        Console.WriteLine(str);
        if (String.IsNullOrEmpty(str) || Char.IsLower(str, 0))
            return str;

        return Char.ToLowerInvariant(str[0]) + str.Substring(1);
    }
}
4
  • 1
    string pattern = @"@Model\.(?<name>\w+)"; Commented Aug 18, 2015 at 15:53
  • @AvinashRaj, but still passing just ${name} to the FirstCharacterToLower, is there any way I can access that named group as a normal variable? Commented Aug 18, 2015 at 15:59
  • 1
    Use a replace delegate. Also its not clear what you are trying to find. You just need to make a regex that matches any key you're looking for, replace the value inside the delegate (callback). Commented Aug 18, 2015 at 16:12
  • 1
    Thanks @sln, I eventually made it work based on your comment Commented Aug 18, 2015 at 16:39

2 Answers 2

1

As @sln told, you have to use delegate.

private static String Replace(String str)
{
    var dictionary = new Dictionary<string, string>
    {
        {"primaryColour", "blue"},
        {"secondaryColour", "red"}
    };

    string pattern = @"@Model\.(?<name>\w+)";
    return Regex.Replace(str, pattern, m => 
        {
            string key = m.Groups["name"].Value;
            key = FirstCharacterToLower(key);
            string value = null;
            if (dictionary.TryGetValue(key, out value))
                return value;
            else
                return m.Value;
        });
}
Sign up to request clarification or add additional context in comments.

1 Comment

Yeah, got tot pretty much the same solution as per my edit. But definitely this works
1

You'd be better off describing a general regex that matches all your
keys. Then using a delegate replacement.

var dictionary = new Dictionary<string, string>
{
    {"primarycolour", "blue"},
    {"secondarycolour", "red"}
};

string line_original =
@"
// Colour
$primary-colour: if(@Model.PrimaryColour, @primaryColour, #afd05c);
$secondary-colour: if(@secondaryColour, @secondaryColour, #323f47);
// and so on
";

Regex RxColors = new Regex( @"@Model\.(?<name>\w+)" );
string line_new = RxColors.Replace(
    line_original,
    delegate(Match match)
    {
        string outVal;
        if ( dictionary.TryGetValue( match.Groups["name"].Value.ToLower(), out outVal) )
            return outVal;
        return match.Groups[0].Value;
    }
);
Console.WriteLine("New line: \r\n\r\n{0}", line_new );

Output:

New line:

// Colour
$primary-colour: if(blue, @primaryColour, #afd05c);
$secondary-colour: if(@secondaryColour, @secondaryColour, #323f47);
// and so on

1 Comment

Thanks, worked on it at the same time based on sln comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.