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

入口:

hoho
hihi
haha
hede

代码:

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

所需的产量:

hoho
hihi
haha

当前回答

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

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

其他回答

如果你想匹配一个字符,否认类似于否认字符类的单词:

例如,一条线:

<?
$str="aaa        bbb4      aaa     bbb7";
?>

不要使用:

<?
preg_match('/aaa[^bbb]+?bbb7/s', $str, $matches);
?>

使用:

<?
preg_match('/aaa(?:(?!bbb).)+?bbb7/s', $str, $matches);
?>

警告“(?!bbb.)”不是 lookbehind 或 lookahead,它是 lookcurrent,例如:

"(?=abc)abcde", "(?!abc)abcde"

这就是我这样做的方式:

^[^h]*(h(?!ede)[^h]*)*$

比其他答案更准确、更有效,它实施了弗里德尔的“无滚动”效率技术,需要更少的后续追踪。

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

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

基准

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

参考文本:

第一 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功能。

也许你会在谷歌上找到这一点,同时试图写一个能够匹配一行(与整个行相反)的分区,这些分区不包含一个字符。

根据字符串: <span class="good">bar</span><span class="bad">foo</span><span class="ugly">baz</span>

我想匹配 <span> 标签,这些标签不包含“坏”字符。

/<span(?:(?!坏)*?>将匹配 <span class=\"good\">和 <span class=\"ugly\">。

请注意,有两组(层)的偏见:

最内在的是对负面观点(这不是捕捉群体) 最外在是由Ruby作为捕捉群体解释的,但我们不希望它成为捕捉群体,所以我补充说:它是开始,它不再被解释为捕捉群体。

在Ruby中展示:

s = '<span class="good">bar</span><span class="bad">foo</span><span class="ugly">baz</span>'
s.scan(/<span(?:(?!bad).)*?>/)
# => ["<span class=\"good\">", "<span class=\"ugly\">"]