【问题标题】:String replace with dictionary exception handling用字典异常处理替换字符串
【发布时间】:2014-10-23 15:13:06
【问题描述】:

我已经在这里实现了对字符串进行令牌替换的答案: https://stackoverflow.com/a/1231815/1224021

我现在的问题是当这个方法找到一个值不在字典中的标记时。我收到异常“字典中不存在给定的键”。并返回正常的字符串。我显然希望发生的事情是所有好的令牌都被替换,但有问题的令牌仍然是自然的。猜猜我需要做一个循环与单行正则表达式替换?使用 vb.net。这是我目前正在做的事情:

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

【问题讨论】:

  • 在哪一行抛出异常?

标签: regex vb.net dictionary replace token


【解决方案1】:

异常可能是在行中抛出的

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

因为这是您键入字典的唯一位置。在访问之前使用Dictionary.ContainsKey method

retval = re.Replace(val, 
             Function(match)
                 return If(args.ContainsKey(match.Groups(1).Value), args(match.Groups(1).Value), val)
             End Function)

【讨论】:

  • 我认为这可行,但现在看到它弄乱了我的 html 字符串。当遇到缺少的字典条目时,它会重复或替换错误的部分。感谢您让我知道 ContainsKey。
【解决方案2】:

这是我要与正则表达式相比的工作,这也是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

【讨论】:

    【解决方案3】:

    我知道这个问题已经有一段时间没有回答了,但对于任何想要仍然使用正则表达式/字典匹配方法的人来说,仅供参考,以下工作(基于 OP 问题中的示例):

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

    ...或者我作为字符串扩展方法的完整示例是:

     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;
                }
            }
    

    这里有几点需要注意: 1) 我的参数作为 JSON 数组传入,例如:{"ProjectCode":"12345","AnotherParam":"Hi there!"} 2) 进行替换的实际模板/格式字符串具有用双花括号括起来的参数:"This is the Project Code: {{ProjectCode}}, this is another param {{AnotherParam}}" 3) 正则表达式既被延迟初始化又被编译以适合我的特定用例:

    • 此代码服务的屏幕可能不经常使用
    • 但一旦使用,它就会被大量使用
    • 因此在后续调用中应该尽可能高效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-15
      • 1970-01-01
      • 2018-09-11
      相关资源
      最近更新 更多