我知道可以匹配一个单词,然后用其他工具逆转比赛(例如 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
其他回答
基准
我决定评估一些提交的选项,并比较其性能,以及使用一些新功能。
参考文本:
第一 7 行不应匹配,因为它们包含所搜索的表达式,而下 7 行应匹配!
Regex Hero is a real-time online Silverlight Regular Expression Tester.
XRegex Hero is a real-time online Silverlight Regular Expression Tester.
Regex HeroRegex HeroRegex HeroRegex HeroRegex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her Regex Her Regex Her Regex Her Regex Her Regex Her Regex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her is a real-time online Silverlight Regular Expression Tester.Regex Hero
egex Hero egex Hero egex Hero egex Hero egex Hero egex Hero Regex Hero is a real-time online Silverlight Regular Expression Tester.
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRegex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her
egex Hero
egex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her is a real-time online Silverlight Regular Expression Tester.
Regex Her Regex Her Regex Her Regex Her Regex Her Regex Her is a real-time online Silverlight Regular Expression Tester.
Nobody is a real-time online Silverlight Regular Expression Tester.
Regex Her o egex Hero Regex Hero Reg ex Hero is a real-time online Silverlight Regular Expression Tester.
结果:
结果是每秒以 3 轮的平均值 - 大数 = 更好
01: ^((?!Regex Hero).)*$ 3.914 // Accepted Answer
02: ^(?:(?!Regex Hero).)*$ 5.034 // With Non-Capturing group
03: ^(?!.*?Regex Hero).* 7.356 // Lookahead at the beginning, if not found match everything
04: ^(?>[^R]+|R(?!egex Hero))*$ 6.137 // Lookahead only on the right first letter
05: ^(?>(?:.*?Regex Hero)?)^.*$ 7.426 // Match the word and check if you're still at linestart
06: ^(?(?=.*?Regex Hero)(?#fail)|.*)$ 7.371 // Logic Branch: Find Regex Hero? match nothing, else anything
P1: ^(?(?=.*?Regex Hero)(*FAIL)|(*ACCEPT)) ????? // Logic Branch in Perl - Quick FAIL
P2: .*?Regex Hero(*COMMIT)(*FAIL)|(*ACCEPT) ????? // Direct COMMIT & FAIL in Perl
由于.NET 不支持操作 Verbs (*FAIL 等) 我无法测试 P1 和 P2 解决方案。
总结:
总的来说,最可读和最快的解决方案似乎是03与一个简单的负面视图,这也是JavaScript的最快的解决方案,因为JS不支持其他解决方案的更先进的Regex功能。
这就是我这样做的方式:
^[^h]*(h(?!ede)[^h]*)*$
比其他答案更准确、更有效,它实施了弗里德尔的“无滚动”效率技术,需要更少的后续追踪。
我能找到的最简单的事情就是
[^(hede)]
在 https://regex101.com/ 上测试
您也可以在该网站上添加单元测试案例
更简单的解决方案是使用非运营商!
如果您的声明需要匹配“内容”而不匹配“排除”。
var contains = /abc/;
var excludes =/hede/;
if(string.match(contains) && !(string.match(excludes))){ //proceed...
我相信RegEx的设计师预测了非运营商的使用。
如果您希望 regex 测试只会失败,如果整个序列相匹配,则下列内容将工作:
^(?!hede$).*
例如 - 如果你想允许除了“foo”以外的所有值(即“foofoo”,“barfoo”和“foobar”将通过,但“foo”将失败),请使用: ^(?!foo$)。
当然,如果你正在检查准确的平等,在这种情况下,一个更好的总体解决方案是检查序列平等,也就是说。
myStr !== 'foo'
您甚至可以将拒绝置于测试之外,如果您需要任何 regex 功能(这里,案例不敏感性和范围匹配):
!/^[a-f]oo$/i.test(myStr)
但是,这个答案的顶部的 regex 解决方案在需要积极的 regex 测试的情况下可能有用(可能是通过 API)。