我知道可以匹配一个单词,然后用其他工具逆转比赛(例如 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
当前回答
只要你正在处理线路,只需标记负面比赛,并瞄准其余。
事实上,我用这个技巧与 sed 因为 ^(?!hede)*$ 看起来不受它支持。
对于所需的产量
标记负面相匹配:(例如,线与目标),使用一个字符不包含在整个文本,一个 emoji 可能是一个很好的选择为此目的。 s/(*hede)/\1/g 目标其余(未标记的线:例如,线与目标无目标)。 假设你只想保持目标并删除其余(如你想要): s/^。
为了更好的理解
假设你想删除目标:
其他回答
有了负面看法,正常的表达可以匹配一些不包含特定的模式的东西,这是由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()
);
基准
我决定评估一些提交的选项,并比较其性能,以及使用一些新功能。
参考文本:
第一 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功能。
下面的功能将帮助您获得所需的产量
<?PHP
function removePrepositions($text){
$propositions=array('/\bfor\b/i','/\bthe\b/i');
if( count($propositions) > 0 ) {
foreach($propositions as $exceptionPhrase) {
$text = preg_replace($exceptionPhrase, '', trim($text));
}
$retval = trim($text);
}
return $retval;
}
?>
更简单的解决方案是使用非运营商!
如果您的声明需要匹配“内容”而不匹配“排除”。
var contains = /abc/;
var excludes =/hede/;
if(string.match(contains) && !(string.match(excludes))){ //proceed...
我相信RegEx的设计师预测了非运营商的使用。
另一个选项是要添加一个积极的视图,并检查视图是否在输入线的任何地方,然后我们会否认,与类似的表达:
^(?!(?=.*\bhede\b)).*$
用词界限。
这个表达式在 regex101.com 的右上方面板上解释,如果你想探索/简化/修改它,在此链接中,你可以看到它会如何与某些样品输入相匹配,如果你愿意。
雷格斯循环
jx.im 可视为常见的表达式:
此分類上一篇