【问题标题】:Find specific word in reg ex along with special character在正则表达式中查找特定单词以及特殊字符
【发布时间】:2016-04-28 06:26:29
【问题描述】:
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,那么它会搜索这些值。

我想搜索带有$ 符号的值。

【问题讨论】:

  • 请妥善安排您的代码。不可读。
  • "$" 在 Regex 中具有特殊含义。用 \ 转义它。但在您的情况下,您将不得不执行 String.Replace() 方法,因为您的正则表达式已生成。您可能还有其他特殊字符...

标签: c# regex regex-lookarounds regex-greedy boost-regex


【解决方案1】:

处理在正则表达式中具有特殊含义但必须按原样搜索的字符的正确方法是转义它们。您可以使用Regex.Escape 执行此操作。在您的情况下,它是 $ 符号,表示正则表达式中的 行尾,如果没有转义。

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# 表达式着色不同。)

【讨论】:

  • 我不知道 Regex.Escape!
【解决方案2】:

目前还不清楚最终目标是什么,但模式中的 $ 是一种模式转义,这意味着行尾或缓冲区结束,具体取决于是否设置了 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
     });

结果

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多