我知道可以匹配一个单词,然后用其他工具逆转比赛(例如 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
当前回答
TXR 语言支持 regex 拒绝。
$ txr -c '@(repeat)
@{nothede /~hede/}
@(do (put-line nothede))
@(end)' Input
一个更复杂的例子:匹配所有从 a 开始和 z 结束的线条,但不包含底层的线条:
$ txr -c '@(repeat)
@{nothede /a.*z&~.*hede.*/}
@(do (put-line nothede))
@(end)' -
az <- echoed
az
abcz <- echoed
abcz
abhederz <- not echoed; contains hede
ahedez <- not echoed; contains hede
ace <- not echoed; does not end in z
ahedz <- echoed
ahedz
雷格克斯的拒绝本身并不特别有用,但当你也有交叉时,事情变得有趣,因为你有一个完整的布莱恩组操作:你可以表达“与此相匹配的组,除了与此相匹配的东西”。
其他回答
TXR 语言支持 regex 拒绝。
$ txr -c '@(repeat)
@{nothede /~hede/}
@(do (put-line nothede))
@(end)' Input
一个更复杂的例子:匹配所有从 a 开始和 z 结束的线条,但不包含底层的线条:
$ txr -c '@(repeat)
@{nothede /a.*z&~.*hede.*/}
@(do (put-line nothede))
@(end)' -
az <- echoed
az
abcz <- echoed
abcz
abhederz <- not echoed; contains hede
ahedez <- not echoed; contains hede
ace <- not echoed; does not end in z
ahedz <- echoed
ahedz
雷格克斯的拒绝本身并不特别有用,但当你也有交叉时,事情变得有趣,因为你有一个完整的布莱恩组操作:你可以表达“与此相匹配的组,除了与此相匹配的东西”。
答案非常好,只是一个学术点:
计算机科学的理论意义上的常规表达是不可能这样做的,对他们来说,它应该看起来像这样:
^([^h].*$)|(h([^e].*$|$))|(he([^h].*$|$))|(heh([^e].*$|$))|(hehe.+$)
这只是一场完整的比赛,做下一场比赛会更可怕。
如果您希望 regex 测试只会失败,如果整个序列相匹配,则下列内容将工作:
^(?!hede$).*
例如 - 如果你想允许除了“foo”以外的所有值(即“foofoo”,“barfoo”和“foobar”将通过,但“foo”将失败),请使用: ^(?!foo$)。
当然,如果你正在检查准确的平等,在这种情况下,一个更好的总体解决方案是检查序列平等,也就是说。
myStr !== 'foo'
您甚至可以将拒绝置于测试之外,如果您需要任何 regex 功能(这里,案例不敏感性和范围匹配):
!/^[a-f]oo$/i.test(myStr)
但是,这个答案的顶部的 regex 解决方案在需要积极的 regex 测试的情况下可能有用(可能是通过 API)。
有了负面看法,正常的表达可以匹配一些不包含特定的模式的东西,这是由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).)*$
解释:
^ 序列的开始,(组和捕获到 \1 (0 或更多次(匹配尽可能多的数量)),(?! 向前看,看看是否存在,
把你的绳子,
(注:因为你在捕获中使用量子,只有捕获模式的最后重复将存储在1美元之前的选项,而字符的结尾。