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

入口:

hoho
hihi
haha
hede

代码:

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

所需的产量:

hoho
hihi
haha

当前回答

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

^(?!hede).*$

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

^((?!hede).)*$

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

其他回答

# 一个简单的方式
import re
skip_word = 'hede'
stranger_char = '虩'
content = '''hoho
hihi
haha
hede'''
print(
    '\n'.join(re.findall(
        '([^{}]*?)\n'.format(stranger_char), 
        content.replace(skip_word, stranger_char)
    )).replace(stranger_char, skip_word) 
)

# hoho
# hihi
# haha

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

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

有了负面看法,正常的表达可以匹配一些不包含特定的模式的东西,这是由Bart Kiers回答和解释的。

但是,与Bart Kiers的答案, lookahead 部分将测试 1 到 4 个字符在前面,同时匹配任何一个字符. 我们可以避免这一点,让 lookahead 部分检查整个文本,确保没有“hede”,然后正常部分(*)可以同时吃整个文本。

下面是改进的雷格斯:

/^(?!.*?hede).*$/

请注意,在负面 lookahead 部分的 (*?) lazy 量子是可选的,您可以根据您的数据使用 (*) greedy 量子:如果“hede”是存在的,在文本的初半, lazy 量子可以更快;否则, greedy 量子会更快。

这里是Demo代码。

此外,请查看RegexGen.js,一个JavaScript常规表达式发明器,有助于构建复杂的常规表达式。

var _ = regexGen;

var regex = _(
    _.startOfLine(),             
    _.anything().notContains(       // match anything that not contains:
        _.anything().lazy(), 'hede' //   zero or more chars that followed by 'hede',
                                    //   i.e., anything contains 'hede'
    ), 
    _.endOfLine()
);

^((?!hede).)*$

而且,如果你需要匹配线打破车也,使用DOT-ALL修改器(在下面的模式中的跟踪器):

/^((?!hede).)*$/s

或使用 inline:

/(?s)^((?!hede).)*$/

如果 DOT-ALL 修改器不适用,您可以模拟相同的行为与字符类 [\s\S]:

/^((?!hede)[\s\S])*$/

解释

    ┌──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┐
S = │e1│ A │e2│ B │e3│ h │e4│ e │e5│ d │e6│ e │e7│ C │e8│ D │e9│
    └──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┘
    
index    0      1      2      3      4      5      6      7

在哪里是e的是空的线条. 雷格斯(?!hede)看向前看,看看是否没有任何字符的“hede”可以看到,如果是这样的情况(所以另一个东西可以看到),那么.(dot)将匹配任何字符,除了线条中断。

正如你可以看到的,输入“ABhedeCD”将失败,因为在e3上, regex(?!hede)失败(有“hede”在前面!)。

自推出Ruby-2.4.1以来,我们可以在Ruby的常规表达中使用新缺席运营商。

官方DOC

(?~abc) matches: "", "ab", "aab", "cccc", etc.
It doesn't match: "abc", "aabc", "ccccabc", etc.

因此,在你的情况下 ^(?~hede)$ 为你做工作

2.4.1 :016 > ["hoho", "hihi", "haha", "hede"].select{|s| /^(?~hede)$/.match(s)}
 => ["hoho", "hihi", "haha"]