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

入口:

hoho
hihi
haha
hede

代码:

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

所需的产量:

hoho
hihi
haha

当前回答

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

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

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

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

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

其他回答

基准

我决定评估一些提交的选项,并比较其性能,以及使用一些新功能。

参考文本:

第一 7 行不应匹配,因为它们包含所搜索的表达式,而下 7 行应匹配!

Regex Hero is a real-time online Silverlight Regular Expression Tester.
XRegex Hero is a real-time online Silverlight Regular Expression Tester.
Regex HeroRegex HeroRegex HeroRegex HeroRegex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her Regex Her Regex Her Regex Her Regex Her Regex Her Regex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her is a real-time online Silverlight Regular Expression Tester.Regex Hero
egex Hero egex Hero egex Hero egex Hero egex Hero egex Hero Regex Hero is a real-time online Silverlight Regular Expression Tester.
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRegex Hero is a real-time online Silverlight Regular Expression Tester.

Regex Her
egex Hero
egex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her is a real-time online Silverlight Regular Expression Tester.
Regex Her Regex Her Regex Her Regex Her Regex Her Regex Her is a real-time online Silverlight Regular Expression Tester.
Nobody is a real-time online Silverlight Regular Expression Tester.
Regex Her o egex Hero Regex  Hero Reg ex Hero is a real-time online Silverlight Regular Expression Tester.

结果:

结果是每秒以 3 轮的平均值 - 大数 = 更好

01: ^((?!Regex Hero).)*$                    3.914   // Accepted Answer
02: ^(?:(?!Regex Hero).)*$                  5.034   // With Non-Capturing group
03: ^(?!.*?Regex Hero).*                   7.356   // Lookahead at the beginning, if not found match everything
04: ^(?>[^R]+|R(?!egex Hero))*$             6.137   // Lookahead only on the right first letter
05: ^(?>(?:.*?Regex Hero)?)^.*$             7.426   // Match the word and check if you're still at linestart
06: ^(?(?=.*?Regex Hero)(?#fail)|.*)$       7.371   // Logic Branch: Find Regex Hero? match nothing, else anything

P1: ^(?(?=.*?Regex Hero)(*FAIL)|(*ACCEPT))  ?????   // Logic Branch in Perl - Quick FAIL
P2: .*?Regex Hero(*COMMIT)(*FAIL)|(*ACCEPT) ?????   // Direct COMMIT & FAIL in Perl

由于.NET 不支持操作 Verbs (*FAIL 等) 我无法测试 P1 和 P2 解决方案。

总结:

总的来说,最可读和最快的解决方案似乎是03与一个简单的负面视图,这也是JavaScript的最快的解决方案,因为JS不支持其他解决方案的更先进的Regex功能。

^hede$(*SKIP)(*F)|^.*$

这将完全滑动包含准确的线条的线条,并匹配所有剩下的线条。

演示

符号前的部分. 符号不应匹配. ^hede$(*SKIP)(*F) 符号后的部分. 符号应匹配。

第一部分

^hede$(*SKIP)(*F)

解释:

因此,包含字符串的线条将被匹配. 一旦雷格斯发动机看到以下 (*SKIP)(*F)(注:你可以写 (*F)作为 (*FAIL))字符,它滑动并使匹配失败。

第2部分

^.*$

解释:

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

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

相当于(为.net ):

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

老答案:

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

此前提到的(?(?!)*是很棒的,因为它可以被 anchored。

^(?:(?!hede).)*$               # A line without hede

foo(?:(?!hede).)*bar           # foo followed by bar, without hede between them

但在这种情况下,以下几点就足够了:

^(?!.*hede)                    # A line without hede

此简化已准备好添加“和”条款:

^(?!.*hede)(?=.*foo)(?=.*bar)   # A line with foo and bar, but without hede
^(?!.*hede)(?=.*foo).*bar       # Same

^((?!hede).) *$ 是一个优雅的解决方案,除非它消耗字符,你将无法将其与其他标准相结合。 例如,说你想检查“hede”的不存在和“haha”的存在。

^(?!.*\bhede\b)(?=.*\bhaha\b)