我知道可以匹配一个单词,然后用其他工具逆转比赛(例如 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) 

其他回答

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

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

演示

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

第一部分

^hede$(*SKIP)(*F)

解释:

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

第2部分

^.*$

解释:

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

例如,一条线:

<?
$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"

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

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

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

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

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

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

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

请注意,解决方案不会从“现在”开始:

^(?!hede).*$

一般来说,它比解决方案不包含“这些”的更有效:

^((?!hede).)*$

前者只在输入行的第一个位置检查“点”而不是每个位置。