regex 在C#中使用正则表达式.替换为MatchEvaluator函数

uxh89sit  于 2023-01-18  发布在  C#
关注(0)|答案(1)|浏览(156)

我有下面这段代码

private void ReplaceVariables(DynamicForm form, DynamicEmailTemplate emailTemplate, List<DynamicFieldValue> fieldValues)
 {
     Regex regex = new Regex("\\?([\\w-]+)\\?", RegexOptions.IgnoreCase);

     // Replace Form Display Title Variables
     MatchCollection formDisplayTitleRegexMatches = regex.Matches(form.FormDisplayTitle);

     if (formDisplayTitleRegexMatches.Count > 0)
     {
         foreach (Match formDisplayTitleRegexMatch in formDisplayTitleRegexMatches)
         {
             foreach (var fieldValue in fieldValues)
             {
                 var formformDisplayTitleRegexMatchRemovedQuestionMarks = formDisplayTitleRegexMatch.Groups[1].Value;

                 if (formformDisplayTitleRegexMatchRemovedQuestionMarks.Equals(fieldValue.FieldCode))
                 {
                     form.FormDisplayTitle = form.FormDisplayTitle.Replace(formDisplayTitleRegexMatch.Value, fieldValue.Value);
                 }
             }
         }
     }
}
IEnumerable<string> labelsInEmailTemplate = emailTemplate
  .Entries
  .Select(x => x.FormField.FieldDefinition.FieldLabel);

foreach (string labelInEmailTemplate in labelsInEmailTemplate)
{
    MatchCollection labelRegexMatches = regex.Matches(labelInEmailTemplate);

    if (labelRegexMatches.Count > 0)
    {
        foreach (Match labelRegexMatch in labelRegexMatches)
        {
            foreach (DynamicFieldValue fieldValue in fieldValues)
            {
                string labelRegexMatchRemovedQuestionMarks = labelRegexMatch.Groups[1].Value;

                if (labelRegexMatchRemovedQuestionMarks.Equals(fieldValue.FieldCode))
                {
                    DynamicEmailTemplateEntry emailTemplateEntryToUpdate = emailTemplate
                        .Entries
                        .Find(x => x
                            .FormField
                            .FieldDefinition
                            .FieldLabel
                            .Contains(labelRegexMatch.Value));

                    emailTemplateEntryToUpdate
                        .FormField
                        .FieldDefinition
                        .FieldLabel = emailTemplateEntryToUpdate
                             .FormField
                             .FieldDefinition
                             .FieldLabel
                             .Replace(labelRegexMatch.Value, WebUtility.HtmlEncode(fieldValue.Value));
                }
            }
        }
    }
}

示例标题变量可以是-?MY_Title? and ?MyName?
我有2个foreach循环,是否可以使用MatchEvaluator和传递给Regex.Replace的委托?
做了另一个更新,当我有2个foreach循环时是否可以使用Replace,因为我不能通过foreach循环更新记录。

f87krz0w

f87krz0w1#

是的,你可以试着把你的代码重写成Regex.Replace,就像这样:

Regex regex = new Regex(@"\?[\w-]+\?", RegexOptions.IgnoreCase);

form.FormDisplayTitle = regex.Replace(form.FormDisplayTitle, match => {
  // get rid of leading and trailing ?
  var name = match.Value.Trim('?');

  // check if match corresponds to any FieldCode
  foreach (var fieldValue in fieldValues) 
    if (name.Equals(fieldValue.FieldCode))
      return fieldValue.Value; // Code found, Value returned
  
  // Unknown FieldCode, do nothing (return match intact)
  return match.Value; 
});

这里对于每个match调用lambda函数,我们应该返回替换:fieldValue.Value或匹配自身-match.Value-如果尚未找到值。

**更新:**第二个片段可重写如下:

// For each entry in emailTemplate.Entries
foreach (var DynamicEmailTemplateEntry entry in emailTemplate.Entries) {
  // given lable teemplate...
  string labelTemplate = entry
    .FormField
    .FieldDefinition
    .FieldLabel;

  // ... we compute actual label
  string updatedLabel = regex.Replace(labelTemplate, match => {
    var name => match.Value.Trim('?');
  
    // either FieldValue or match as it is
    return fieldValue
      .Where(fv => fv.FieldCode == name)
      .Select(fv => fv.Value)
      .FirstOrDefault(match.Value);
  });

  // which we assign to template 
  entry
    .FormField
    .FieldDefinition
    .FieldLabel = updatedLabel; 
}

相关问题