不包含多个特定单词的字符串正则表达式

68

我正在尝试编写一个正则表达式来查找字符串中特定单词不存在的情况。具体而言,我想知道当"trunk"、"tags"或者"branches"不存在时(这是用于Subversion pre-commit hook的),该如何操作。根据匹配不包含某个单词的正则表达式答案,我可以使用负向先行断言来轻松地处理一个单词的情况:

^((?!trunk).)*$

我正在遇到困难的是“and”运算符,而且我似乎不能让另外两个词也起作用。

在.NET中,单个单词已经可以正常运行:

var exp = new Regex(@"^((?!trunk).)*$");
exp.IsMatch("trunk/blah/blah");

如果代码第二行的路径中不存在"trunk",则该代码将返回true;否则,它将返回false。 我错在哪里了?


为什么你不能只是做一个正常的“搜索”正则表达式,然后反转结果呢? - Lasse V. Karlsen
1
我受到限制,只能编辑正则表达式,而不能编辑周围的逻辑。 - Troy Hunt
2个回答

135

使用一个负面的前瞻断言,它断言了输入中没有这三个单词的任何地方:

^(?!.*(trunk|tags|branches)).*$

我还稍微重新排列了你的正则表达式,以纠正一些小错误。


4
由于预查不消耗任何输入,因此您需要在外部留下一些内容以进行实际匹配。如果将 .* 移至预查内部,则只剩下 ^$,它实际上不匹配任何内容(即一个空白),再加上一个匹配了 某些内容 的预查,这是不可能的。 - Bohemian

5
使用“标准”匹配并查找!IsMatch
var exp = new Regex(@"trunk|tags|branches");
var result = !exp.IsMatch("trunk/blah/blah");

为什么人们喜欢把生活弄得更加困难呢?
啊...还要记住“ass原则”!http://www.codinghorror.com/blog/2008/10/obscenity-filters-bad-idea-or-incredibly-intercoursing-bad-idea.html 因此最好写成:
var exp = new Regex(@"\b(trunk|tags|branches)\b");

但是如果你真的需要一个负向先行断言表达式,并且遵循“ass”原则

var exp = new Regex(@"^(?!.*\b(trunk|tags|branches)\b)";

测试人员:http://gskinner.com/RegExr/?2uv1g

我需要指出的是,如果你正在寻找完整路径(由/\分隔的单词),那么

var exp = new Regex(@"^(?!.*(^|\\|/)(trunk|tags|branches)(/|\\|$))";

测试人员: http://gskinner.com/RegExr/?2uv1p


1
谢谢,但不幸的是,在这种情况下,约束条件要求在正则表达式中完成工作,我无法控制代码以外的部分来反转条件。 - Troy Hunt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接