我需要验证字符串是否包含"错误"或"例外"其中,不包括某些关键字:" 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
"的匹配。
我在这里缺少什么?
答案 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测试仪可以帮助您找出实际匹配的内容。我用过这个:
在突出显示匹配项的结果中,有一个小按钮,其中包含“i”信息。因此,当它不区分大小写时匹配innerException
的原因是因为你匹配了单词的后半部分。正则表达式不需要用空格分隔单词。
如果innerException
被写为innerexception
,您的正则表达式将与案例不变量匹配,因为您的正匹配(exception|error)
与后半部分匹配。您还可以在开始删除空格时看到。 exception1exception2
不匹配,但exception1exception2exception3
会匹配。
虽然Regex非常紧凑,但有几种方法可以解决它。在这种情况下,直接的方法可能是更好的解决方案。
更改正则表达式以删除最后一个通配符*
字符将使您按照自己的方式工作:
\b\w*(?!exception1)(?!exception2)(?!includeException)(?!error1)(exception|error)\w\b
答案 2 :(得分:2)
我看到你的正则表达式存在两个主要瓶颈:
\w*
子图案放置在前瞻的两侧,从而消除前瞻中的任何影响。 Berin的答案中描述了不区分大小写的问题,您希望匹配单词exception
和includeException
包含该子字符串。因此,一个可能的解决方案是向(error|exception)
模式添加一个前导词边界:
\b\w*(?!exception1)(?!exception2)(?!includeException)(?!error1)\b(exception|error)\w*\b
^^
但是,如果您需要匹配包含error
或exception
,与特定关键字不相等的字词,请使用
\b(?!(?:exception1|exception2|includeException|error1)\b)\w*(exception|error)\w*\b
这里,前瞻被锚定到前导词边界,它们仅在每个单词边界之后一次检查,而不是在单词内的每个位置。当然,您可以进一步签订合同:\b(?!(?:exception[12]|includeException|error1)\b)\w*(exception|error)\w*\b
。
现在,如果您需要匹配包含error
或exception
,不包含特定关键字的字词,请使用
\b(?!\w*(?:exception1|exception2|includeException|error1))\w*(exception|error)\w*\b
此处使用的所有正则表达式模式均在regexhero.net
进行测试