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

入口:

hoho
hihi
haha
hede

代码:

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

所需的产量:

hoho
hihi
haha

当前回答

答案:

^((?!hede).)*$

解释:

^ 序列的开始,(组和捕获到 \1 (0 或更多次(匹配尽可能多的数量)),(?! 向前看,看看是否存在,

把你的绳子,

(注:因为你在捕获中使用量子,只有捕获模式的最后重复将存储在1美元之前的选项,而字符的结尾。

其他回答

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

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

/.*hede(*COMMIT)^|/

它是如何工作的

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

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

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

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

原因在于,没有旗帜,POSIX接口只需要使用基本常规表达式(BRE),这些表达式只是不足以完成这个任务,因为缺乏替代的子表达式。

grep "^\([^h]\|h\(h\|eh\|edh\)*\([^eh]\|e[^dh]\|ed[^eh]\)\)*\(\|h\(h\|eh\|edh\)*\(\|e\|ed\)\)$" input

(与格雷尔和一些额外的优化手工完成)。

egrep "^([^h]|h(h|eh|edh)*([^eh]|e[^dh]|ed[^eh]))*(|h(h|eh|edh)*(|e|ed))$" input

#!/bin/bash
REGEX="^\([^h]\|h\(h\|eh\|edh\)*\([^eh]\|e[^dh]\|ed[^eh]\)\)*\(\|h\(h\|eh\|edh\)*\(\|e\|ed\)\)$"

# First four lines as in OP's testcase.
cat > testinput.txt <<EOF
hoho
hihi
haha
hede

h
he
ah
head
ahead
ahed
aheda
ahede
hhede
hehede
hedhede
hehehehehehedehehe
hedecidedthat
EOF
diff -s -u <(grep -v hede testinput.txt) <(grep "$REGEX" testinput.txt)

Files /dev/fd/63 and /dev/fd/62 are identical

如预期。

对于那些对细节感兴趣的人来说,使用的技术是将与词相匹配的常规表达式转换为终端自动,然后转换自动,将每个接受状态转换为不接受,反之亦然,然后将结果的FA转换为常规表达式。

grep -P '^((?!hede).)*$' input

^([^h]|h(h|e(h|dh))*([^eh]|e([^dh]|d[^eh])))*(h(h|e(h|dh))*(ed?)?)?$

我想添加另一个例子,如果你试图匹配一个包含X线的整个线,但也不包含Y线。

这个 regex 模式会工作(在 JavaScript 中也工作)

^(?=.*?tasty-treats)((?!chocolate).)*$

(全球,多线旗在例子中)

互动示例: https://regexr.com/53gv4

比赛

(这些 URL 包含“蛋糕治疗”并且不包含“巧克力”)

example.com/tasty-treats/strawberry-ice-cream example.com/甜点/tasty-treats/banana-pudding example.com/tasty-treats-overview

没有匹配

example.com/tasty-treats/chocolate-cake example.com/home-cooking/over-roasted-chicken example.com/tasty-treats/banana-chocolate-fudge example.com/desserts/chocolate/tasty-treats example.com/chocolate/tasty-treats/desserts

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

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

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

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

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

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