1

I've implemented the answer here to do token replacements of a string: https://stackoverflow.com/a/1231815/1224021

My issue now is when this method finds a token with a value that is not in the dictionary. I get the exception "The given key was not present in the dictionary." and just return the normal string. What I'd like to happen obviously is all the good tokens get replaced, but the offending one remains au naturale. Guessing I'll need to do a loop vs. the one line regex replace? Using vb.net. Here's what I'm currently doing:

Shared ReadOnly re As New Regex("\$(\w+)\$", RegexOptions.Compiled)
Public Shared Function GetTokenContent(ByVal val As String) As String
    Dim retval As String = val

    Try
        If Not String.IsNullOrEmpty(val) AndAlso val.Contains("$") Then

            Dim args = GetRatesDictionary()

            retval = re.Replace(val, Function(match) args(match.Groups(1).Value))

        End If

    Catch ex As Exception

        ' not sure how to handle?

    End Try

    Return retval

End Function
1
  • On what line is the exception thrown? Commented Aug 29, 2014 at 15:16

3 Answers 3

1

The exception is likely thrown in the line

retval = re.Replace(val, Function(match) args(match.Groups(1).Value))

because this is the only place you are keying the dictionary. Make use of the Dictionary.ContainsKey method before accessing it.

retval = re.Replace(val, 
             Function(match)
                 return If(args.ContainsKey(match.Groups(1).Value), args(match.Groups(1).Value), val)
             End Function)
Sign up to request clarification or add additional context in comments.

1 Comment

I thought this worked but now see it messes up my html string. It repeats or replaces the wrong part when encountering a missing dictionary entry. Thanks for letting me know about ContainsKey though.
1

This is what I got to work vs. the regex, which was also a suggestion on the original thread by Allen Wang: https://stackoverflow.com/a/7957728/1224021

Public Shared Function GetTokenContent(ByVal val As String) As String
    Dim retval As String = val

    Try
        If Not String.IsNullOrEmpty(val) AndAlso val.Contains("$") Then

            Dim args = GetRatesDictionary("$")

            retval = args.Aggregate(val, Function(current, value) current.Replace(value.Key, value.Value))

        End If

    Catch ex As Exception

    End Try

    Return retval

End Function

Comments

0

I know it's been a while since this question was answered, but FYI for anyone wanting to still use the Regex / Dictionary match approach, the following works (based on the sample in the OP question):

retVal = re.Replace(formatString,
                    match => args.ContainsKey(match.Groups[1].Captures[0].Value)
                        ? args[match.Groups[1].Captures[0].Value]
                        : string.Empty);

... or my full sample as a string extension method is:

 public static class StringExtensions
        {
// Will replace parameters enclosed in double curly braces
            private static readonly Lazy<Regex> ParameterReplaceRegex = new Lazy<Regex>(() => new Regex(@"\{\{(?<key>\w+)\}\}", RegexOptions.Compiled));

            public static string InsertParametersIntoFormatString(this string formatString, string parametersJsonArray)
            {
                if (parametersJsonArray != null)
                {
                    var deserialisedParamsDictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(parametersJsonArray);

                    formatString = ParameterReplaceRegex.Value.Replace(formatString,
                        match => deserialisedParamsDictionary.ContainsKey(match.Groups[1].Captures[0].Value)
                            ? deserialisedParamsDictionary[match.Groups[1].Captures[0].Value]
                            : string.Empty);
                }

                return formatString;
            }
        }

There are a few things to note here: 1) My parameters are passed in as a JSON array, e.g.: {"ProjectCode":"12345","AnotherParam":"Hi there!"} 2) The actual template / format string to do the replacements on has the parameters enclosed in double curly braces: "This is the Project Code: {{ProjectCode}}, this is another param {{AnotherParam}}" 3) Regex is both Lazy initialized and Compiled to suit my particular use case of:

  • the screen this code serves may not be used often
  • but once it is, it will get heavy use
  • so it should be as efficient on subsequent calls as possible.

Comments

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.