我知道可以匹配一个单词,然后用其他工具逆转比赛(例如 grep -v)。但是,可以匹配不包含一个特定的单词,例如 hede,使用常规表达式的线条吗?
入口:
hoho
hihi
haha
hede
代码:
grep "<Regex for 'doesn't contain hede'>" input
所需的产量:
hoho
hihi
haha
我知道可以匹配一个单词,然后用其他工具逆转比赛(例如 grep -v)。但是,可以匹配不包含一个特定的单词,例如 hede,使用常规表达式的线条吗?
入口:
hoho
hihi
haha
hede
代码:
grep "<Regex for 'doesn't contain hede'>" input
所需的产量:
hoho
hihi
haha
当前回答
用此,你避免在每个位置测试一个 lookahead:
/^(?:[^h]+|h++(?!ede))*+$/
相当于(为.net ):
^(?>(?:[^h]+|h+(?!ede))*)$
老答案:
/^(?>[^h]+|h+(?!ede))*$/
其他回答
如果你想匹配一个字符,否认类似于否认字符类的单词:
例如,一条线:
<?
$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的设计师预测了非运营商的使用。
我能找到的最简单的事情就是
[^(hede)]
在 https://regex101.com/ 上测试
您也可以在该网站上添加单元测试案例
它可能更可维持在您的代码中的两个规则,一个进行第一场比赛,然后如果它匹配运行第二个规则,以检查您想要阻止的其他案例,例如 ^.*(hede)。* 然后在您的代码中有适当的逻辑。
好吧,我承认这不是一个真正的答案发表的问题,它也可能使用一些更多的处理,而不是一个单一的 regex. 但对于开发人员谁来到这里寻找一个快速紧急修复的另一个案例,那么这个解决方案不应该被忽视。
^hede$(*SKIP)(*F)|^.*$
这将完全滑动包含准确的线条的线条,并匹配所有剩下的线条。
演示
符号前的部分. 符号不应匹配. ^hede$(*SKIP)(*F) 符号后的部分. 符号应匹配。
第一部分
^hede$(*SKIP)(*F)
解释:
因此,包含字符串的线条将被匹配. 一旦雷格斯发动机看到以下 (*SKIP)(*F)(注:你可以写 (*F)作为 (*FAIL))字符,它滑动并使匹配失败。
第2部分
^.*$
解释: