我知道可以匹配一个单词,然后用其他工具逆转比赛(例如 grep -v)。但是,可以匹配不包含一个特定的单词,例如 hede,使用常规表达式的线条吗?

入口:

hoho
hihi
haha
hede

代码:

grep "<Regex for 'doesn't contain hede'>" input

所需的产量:

hoho
hihi
haha

当前回答

TXR 语言支持 regex 拒绝。

$ txr -c '@(repeat)
@{nothede /~hede/}
@(do (put-line nothede))
@(end)'  Input

一个更复杂的例子:匹配所有从 a 开始和 z 结束的线条,但不包含底层的线条:

$ txr -c '@(repeat)
@{nothede /a.*z&~.*hede.*/}
@(do (put-line nothede))
@(end)' -
az         <- echoed
az
abcz       <- echoed
abcz
abhederz   <- not echoed; contains hede
ahedez     <- not echoed; contains hede
ace        <- not echoed; does not end in z
ahedz      <- echoed
ahedz

雷格克斯的拒绝本身并不特别有用,但当你也有交叉时,事情变得有趣,因为你有一个完整的布莱恩组操作:你可以表达“与此相匹配的组,除了与此相匹配的东西”。

其他回答

答案非常好,只是一个学术点:

计算机科学的理论意义上的常规表达是不可能这样做的,对他们来说,它应该看起来像这样:

^([^h].*$)|(h([^e].*$|$))|(he([^h].*$|$))|(heh([^e].*$|$))|(hehe.+$) 

这只是一场完整的比赛,做下一场比赛会更可怕。

如果你只是用它来捕捉,你可以使用捕捉 -v 以获得所有不包含捕捉的线条。

ETA Oh,重新阅读这个问题,抓 -v 可能是你指的是“工具选项”。

如何使用PCRE的背景跟踪控制字符,以匹配一行不包含单词

下面是我以前从未使用过的一种方法:

/.*hede(*COMMIT)^|/

它是如何工作的

首先,它试图在线上的某个地方找到“故障”。如果成功,在这一点上,(COMMIT)告诉发动机,不只是在故障的情况下不落后,而且也不会试图在这种情况下进一步匹配。

如果一行不包含“干”则第二个替代品,一个空的子模式,成功地匹配主题行。

这个方法不比一个负面看法更有效,但我想我只是把它扔在这里,如果有人发现它是零,并找到一个用于其他,更有趣的应用程序。

用此,你避免在每个位置测试一个 lookahead:

/^(?:[^h]+|h++(?!ede))*+$/

相当于(为.net ):

^(?>(?:[^h]+|h+(?!ede))*)$

老答案:

/^(?>[^h]+|h+(?!ede))*$/

更简单的解决方案是使用非运营商!

如果您的声明需要匹配“内容”而不匹配“排除”。

var contains = /abc/;
var excludes =/hede/;

if(string.match(contains) && !(string.match(excludes))){  //proceed...

我相信RegEx的设计师预测了非运营商的使用。