C#正则表达式匹配包含已知子字符串但不等于特定关键字的字词

时间:2016-01-06 18:26:55

标签: c# regex

我需要验证字符串是否包含"错误"或"例外"其中,不包括某些关键字:" exception1"," exception2"," includeException"," error1"。

这个正则表达式似乎可以完成这项任务:

\b\w*(?!exception1)(?!exception2)(?!includeException)(?!error1)(exception|error)\w*\b

在针对以下字符串运行时正确返回2个匹配项:

Test string: "exception1 exception2 exception3 includeException error1 error2"
Matches: "exception3", "error2"

但是,如果我设置RegexOptions.IgnoreCase标记或添加" (?i)"在正则表达式的开头,它还会返回" includeException"的匹配。

我在这里缺少什么?

3 个答案:

答案 0 :(得分:3)

正则表达式不是很易读......纯粹的C#解决方案怎么样?

public static Boolean ContainsErrorOrExceptionExcept(this string input, string[] excludedKeywords)
{
    if (input.Contains("error") || input.Contains("exception"))
    {
        foreach (string x in excludedKeywords)
        {
            if (input.Contains(x))
            {
                return false;
            }
        }
        return true;
    }
    else
    {
        return false;
    }       
}

答案 1 :(得分:3)

使用优秀的Regex测试仪可以帮助您找出实际匹配的内容。我用过这个:

http://regexhero.net/tester/

在突出显示匹配项的结果中,有一个小按钮,其中包含“i”信息。因此,当它不区分大小写时匹配innerException的原因是因为你匹配了单词的后半部分。正则表达式不需要用空格分隔单词。

如果innerException被写为innerexception,您的正则表达式将与案例不变量匹配,因为您的正匹配(exception|error)与后半部分匹配。您还可以在开始删除空格时看到。 exception1exception2不匹配,但exception1exception2exception3会匹配。

虽然Regex非常紧凑,但有几种方法可以解决它。在这种情况下,直接的方法可能是更好的解决方案。

更改正则表达式以删除最后一个通配符*字符将使您按照自己的方式工作:

\b\w*(?!exception1)(?!exception2)(?!includeException)(?!error1)(exception|error)\w\b

答案 2 :(得分:2)

我看到你的正则表达式存在两个主要瓶颈:

  • 它有几个未发现的前瞻(当没有锚定时,除非在驯化的贪婪令牌和其他复杂模式中使用,否则它们通常没有帮助)
  • \w*子图案放置在前瞻的两侧,从而消除前瞻中的任何影响。

Berin的答案中描述了不区分大小写的问题,您希望匹配单词exceptionincludeException包含该子字符串。因此,一个可能的解决方案是(error|exception)模式添加一个前导词边界

\b\w*(?!exception1)(?!exception2)(?!includeException)(?!error1)\b(exception|error)\w*\b
                                                               ^^

但是,如果您需要匹配包含errorexception 与特定关键字不相等的字词,请使用

\b(?!(?:exception1|exception2|includeException|error1)\b)\w*(exception|error)\w*\b

这里,前瞻被锚定到前导词边界,它们仅在每个单词边界之后一次检查,而不是在单词内的每个位置。当然,您可以进一步签订合同:\b(?!(?:exception[12]|includeException|error1)\b)\w*(exception|error)\w*\b

现在,如果您需要匹配包含errorexception 不包含特定关键字的字词,请使用

\b(?!\w*(?:exception1|exception2|includeException|error1))\w*(exception|error)\w*\b

此处使用的所有正则表达式模式均在regexhero.net

进行测试