我知道可以匹配一个单词,然后用其他工具逆转比赛(例如 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
当前回答
# 一个简单的方式
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
其他回答
这就是我这样做的方式:
^[^h]*(h(?!ede)[^h]*)*$
比其他答案更准确、更有效,它实施了弗里德尔的“无滚动”效率技术,需要更少的后续追踪。
有了负面看法,正常的表达可以匹配一些不包含特定的模式的东西,这是由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()
);
如何使用PCRE的背景跟踪控制字符,以匹配一行不包含单词
下面是我以前从未使用过的一种方法:
/.*hede(*COMMIT)^|/
它是如何工作的
首先,它试图在线上的某个地方找到“故障”。如果成功,在这一点上,(COMMIT)告诉发动机,不只是在故障的情况下不落后,而且也不会试图在这种情况下进一步匹配。
如果一行不包含“干”则第二个替代品,一个空的子模式,成功地匹配主题行。
这个方法不比一个负面看法更有效,但我想我只是把它扔在这里,如果有人发现它是零,并找到一个用于其他,更有趣的应用程序。
如果您希望 regex 测试只会失败,如果整个序列相匹配,则下列内容将工作:
^(?!hede$).*
例如 - 如果你想允许除了“foo”以外的所有值(即“foofoo”,“barfoo”和“foobar”将通过,但“foo”将失败),请使用: ^(?!foo$)。
当然,如果你正在检查准确的平等,在这种情况下,一个更好的总体解决方案是检查序列平等,也就是说。
myStr !== 'foo'
您甚至可以将拒绝置于测试之外,如果您需要任何 regex 功能(这里,案例不敏感性和范围匹配):
!/^[a-f]oo$/i.test(myStr)
但是,这个答案的顶部的 regex 解决方案在需要积极的 regex 测试的情况下可能有用(可能是通过 API)。
更简单的解决方案是使用非运营商!
如果您的声明需要匹配“内容”而不匹配“排除”。
var contains = /abc/;
var excludes =/hede/;
if(string.match(contains) && !(string.match(excludes))){ //proceed...
我相信RegEx的设计师预测了非运营商的使用。