代码之家  ›  专栏  ›  技术社区  ›  Savan Patel

查找reg ex中的特定单词和特殊字符

  •  3
  • Savan Patel  · 技术社区  · 9 年前
    string emailBody = " holla holla testing is for NewFinancial History:\"xyz\"  dsd  NewFinancial History:\"abc\"  NewEBTDI$:\"abc\"  dsds  ";
    
       emailBody = string.Join(" ", Regex.Split(emailBody.Trim(), @"(?:\r\n|\n|\r)"));
                    var keys = Regex.Matches(emailBody, @"\bNew\B(.+?):", RegexOptions.Singleline).OfType<Match>().Select(m => m.Groups[0].Value.Replace(":", "")).Distinct().ToArray();
                    foreach (string key in keys)
                    {
                        List<string> valueList = new List<string>();
                        string regex = "" + key + ":" + "\"(?<" + GetCleanKey(key) + ">[^\"]*)\"";
    
                        var matches = Regex.Matches(emailBody, regex, RegexOptions.Singleline);
                        foreach (Match match in matches)
                        {
                            if (match.Success)
                            {
                                string value = match.Groups[GetCleanKey(key)].Value;
                                if (!valueList.Contains(value.Trim()))
                                {
                                    valueList.Add(value.Trim());
                                }
                            }
                        }
    
     public string GetCleanKey(string key)
            {
                return key.Replace(" ", "").Replace("-", "").Replace("#", "").Replace("$", "").Replace("*", "").Replace("!", "").Replace("@", "")
                    .Replace("%", "").Replace("^", "").Replace("&", "").Replace("(", "").Replace(")", "").Replace("[", "").Replace("]", "").Replace("?", "")
                    .Replace("<", "").Replace(">", "").Replace("'", "").Replace(";", "").Replace("/", "").Replace("\"", "").Replace("+", "").Replace("~", "").Replace("`", "")
                    .Replace("{", "").Replace("}", "").Replace("+", "").Replace("|", "");
            }
    

    在我上面的代码中,我试图获得下面的值 NewEBTDI$: 这是 "abc" .

    当我包括 $ 在模式中签名,它不会搜索字段名旁边的值。

    如果 $ 被删除,其中一个仅指定 NewEBTDI 然后搜索值。

    我想搜索该值以及 $ 标志。

    2 回复  |  直到 9 年前
        1
  •  5
  •   Olivier Jacot-Descombes    9 年前

    处理正则表达式中具有特殊含义但必须按原样搜索的字符的正确方法是对其进行转义。你可以用 Regex.Escape 。在您的情况下 $ 标志,这意味着 线路终点 在regex中,如果没有转义。

    string regex = "" + Regex.Escape(key) + ":" + "\"(?<" + Regex.Escape(GetCleanKey(key))
                   + ">[^\"]*)\"";
    

    string regex = String.Format("{0}:\"(?<{1}>[^\"]*)\"",
                                 Regex.Escape(key),
                                 Regex.Escape(GetCleanKey(key)));
    

    或VS 2015,使用字符串插值:

    string regex = $"{Regex.Escape(key)}:\"(?<{Regex.Escape(GetCleanKey(key))}>[^\"]*)\"";
    

    (它看起来确实比实际情况要好,因为C#编辑器对字符串部分和嵌入的C#表达式进行了不同的着色。)

        2
  •  1
  •   ΩmegaMan    9 年前

    目前尚不清楚最终目标是什么,但 $ 在一个模式中是一个模式转义,它意味着行的结束,或者缓冲区的结束,具体取决于 MultiLine 是否设置。

    为什么不在 : 进入命名捕获?然后提取引用的操作值,如:

    var data = "...is for NewFinancial History:\"xyz\"  dsd  NewFinancial History:\"abc\"  NewEBTDI$:\"abc\"  dsds";
    
    var pattern = @"
    (?<New>New[^:]+)      # Capture all items after `New` that is *not* (`^`) a `:`, one or more.
    :                     # actual `:`
    \x22                  # actual quote character begin anchor
    (?<InQuotes>[^\x22]+) # text that is not a quote, one or more
    \x22                  # actual quote ending anchor
    ";
    
    // IgnorePatternWhitespace allows us to comment the pattern. Does not affect processing.
    Regex.Matches(data, pattern, RegexOptions.IgnorePatternWhitespace | RegexOptions.ExplicitCapture)
         .OfType<Match>()
         .Select(mt => new
         {
             NewText = mt.Groups["New"].Value,
             Text = mt.Groups["InQuotes"].Value
         });
    

    结果

    enter image description here

    注意我使用十六进制转义 \x22 而不是转义 \" 以便于使用。因为它避免了C#编译器过早地转义需要保持完整的模式转义。