Replace {x} tokens in strings

We have a template URL like:

http://api.example.com/sale?auth_user=xxxxx&auth_pass=xxxxx&networkid={networkid}&category=b2c&country=IT&pageid={pageid}&programid=133&saleid=1&m={master}&optinfo={optinfo}&publisher={publisher}&msisdn={userId}

and I have values for these constant tokens. How can replace all these tokens in C#?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

A simple approach is to use a foreach and a Dictionary with a String.Replace:

var values = new Dictionary<string, string> {
    { "{networkid}", "WHEEE!!" }
    // etc.
};
var url = "http://api.example.com/sale?auth_user=xxxxx&auth_pass=xxxxx&networkid={networkid}&category=b2c&country=IT&pageid={pageid}&programid=133&saleid=1&m={master}&optinfo={optinfo}&publisher={publisher}&msisdn={userId}";

foreach(var key in values.Keys){
    url = url.Replace(key,values[key]);
}

Method 2

There is no standard way to “replace with dictionary values” in .NET. While there are a number of template engines, it’s not very hard to write a small solution for such an operation. Here is an example which runs in LINQPad and utilizes a Regular Expression with a Match Evaluator.

As the result is a URL,
it is the callers responsibility to make sure all the supplied values are correctly encoded. I recommend using Uri.EscapeDataString as appropriate .. but make sure to not double-encode, if it is processed elsewhere.

Additionally, the rules of what to do when no replacement is found should be tailored to need. If not-found replacements should be eliminated entirely along with the query string key, the following can expand the regular expression to @"w+=({w+})" to also capture the parameter key in this specific template situation.

string ReplaceUsingDictionary (string src, IDictionary<string, object> replacements) {
    return Regex.Replace(src, @"{(w+)}", (m) => {
        object replacement;
        var key = m.Groups[1].Value;
        if (replacements.TryGetValue(key, out replacement)) {
            return Convert.ToString(replacement);
        } else {
            return m.Groups[0].Value;
        }
    });
}

void Main()
{
    var replacements = new Dictionary<string, object> {
        { "networkid", "WHEEE!!" }
        // etc.
    };
    var src = "http://api.example.com/sale?auth_user=xxxxx&auth_pass=xxxxx&networkid={networkid}&category=b2c&country=IT&pageid={pageid}&programid=133&saleid=1&m={master}&optinfo={optinfo}&publisher={publisher}&msisdn={userId}";
    var res = ReplaceUsingDictionary(src, replacements);

    // -> "http://api.example.com/sale?..&networkid=WHEEE!!&..&pageid={pageid}&..
    res.Dump();
}

More advanced techniques, like reflection and transforms, are possible – but those should be left for the real template engines.

Method 3

I am guessing you are trying to replace parameters in url with your values. This can be done using C# HttpUtility.ParseQueryString

Get the CurrentURL from

   var _myUrl = System.Web.HttpUtility.ParseQueryString(Request.RawUrl);

Read Parameter from your Query string

   string value1 = _myUrl ["networkid"];

Write a value into the QueryString object.

  _myUrl ["networkid"] = "Your Value";

and then finally turn it back into URL

  var _yourURIBuilder= new UriBuilder(_myUrl );
 _myUrl = _yourURIBuilder.ToString();

Method 4

You can use this alos using LinQ

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

myVal.Add("networkid", "1");
myVal.Add("pageid", "2");
myVal.Add("master", "3");
myVal.Add("optinfo", "4");
myVal.Add("publisher", "5");
myVal.Add("userId", "6");

string url = @"http://api.example.com/sale?auth_user=xxxxx&auth_pass=xxxxx&networkid={networkid}&category=b2c&country=IT&pageid={pageid}&programid=133&saleid=1&m={master}&optinfo={optinfo}&publisher={publisher}&msisdn={userId}";
myVal.Select(a => url = url.Replace(string.Concat("{", a.Key, "}"), a.Value)).ToList();

this line can do your required functionlity

myVal.Select(a => url = url.Replace(string.Concat(“{“, a.Key, “}”), a.Value)).ToList();

Method 5

There is a Nuget called StringTokenFormatter that does this well
https://www.nuget.org/packages/StringTokenFormatter/

Method 6

Regex.Replace makes a single pass over a template string, offering you an opportunity to replace matched expressions. Use it by creating an regular expression that matches any token. Then look up replacement values for the tokens in a dictionary.

static string ReplaceTokens(string template, Dictionary<string, string> replacements) =>
    Regex.Replace(template, @"{(w+)}",
        match => replacements.TryGetValue(match.Groups[1].Value, out string replacement) ? replacement : match.Value);

The algorithm completes in time linear with the size of the template string and the replacement strings, so O(t + r). Beware of algorithms that make multiple passes. They run slowly in time O(t * r) and will give incorrect results if one of the replacement values contains a token for later replacement. This unit test shows the pitfall:

public void TestReplaceTokens() {
    var replacements = new Dictionary<string, string> {
        ["Movement"] = "drive {DontReplace}",
        ["DontReplace"] = "Should not appear"
    };
    string withReplacements = ReplaceTokens("I always {Movement} in {Direction}.", replacements);
    Assert.AreEqual("I always drive {DontReplace} in {Direction}.", withReplacements);
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x