所有前瞻和后瞻断言(?=...)
, (?!...)
, (?<=...)
,(?<!...)
不消耗文本。它不会将指针推进到当前位置,这是匹配某些文本时的正常行为。
由于它不推进索引,因此您可以利用此属性来检查文本的多个属性,否则很难在没有前瞻的情况下组合成一个表达式。
在您的情况下,正则表达式检查 string 是否存在bear grylls
,然后在第二次预读中检查是否存在任何字符串。
如果没有前瞻,正则表达式将变为:
^.*?bear grylls.*?(\bnbc\b|reality|episode|show|watch|series|season|premiere)|^.*?(\bnbc\b|reality|episode|show|watch|series|season|premiere).*?bear grylls
由于bear grylls
可以在列表中的任何字符串之前或之后出现,因此您需要交替检查这两种情况。DRY 问题可以通过字符串连接来解决,但是当它不可用时,人们将很难进行维护。
这也是密码验证中经常使用的一种技术,其中可以有多种条件,例如至少一个字母、至少一个数字、至少一个特殊字符、连续没有 3 个相同的字符等。如果你想写一个表达式来检查上面的所有属性,它非常混乱。使用前瞻断言可以让您将所有内容都塞进一个表达式中,而不会使正则表达式变得难以理解和难以维护。
就个人而言,我不太喜欢这种方法,因为将所有内容都塞进一个正则表达式是没有意义的,除非你受到工具的限制并且不允许运行多个正则表达式。我们可以只制作 2 个正则表达式并针对每个测试字符串。性能大致相同,因为在正则表达式引擎中完成了相同数量的工作。事实上,我相信大多数引擎会在上面的正则表达式中重新扫描字符串两次。