我继承了一些正则表达式并试图理解为什么它与某些模式匹配。正则表达式基于正向前瞻断言和匹配文本,如bear grylls episode
。这是有道理的。但它也匹配episode
后跟bear grylls
的文字,例如episode bear grylls
。我没有看到在正则表达式中向后看的任何引用。最后是.*?
让它向后看?
^(?=.*?bear grylls)(?=.*?(\bnbc\b|reality|episode|show|watch|series|season|premiere)).*?
答案 0 :(得分:0)
这解释了它的作用 要修改,这取决于你想做什么。
这是它目前正在做的事情 -
# ^(?=.*?bear\ grylls)(?=.*?(\bnbc\b|reality|episode|show|watch|series|season|premiere)).*?
^ # Beginning of string
(?= # Look ahead
.*? # Ungreedy, any number of characters
bear\ grylls # Must be 'bear grylls' somewhere
) # End lookahead
(?= # Look ahead
.*? # Ungreedy, any number of characters
( # (1 start), Must be one of these somewhere
\b nbc \b
| reality
| episode
| show
| watch
| series
| season
| premiere
) # (1 end)
) # End lookahead
.*? # Assertions passed tests, now match the entire string
我会修改它以获得更好的功能 -
# (?s)^(?=.*\bbear\ grylls\b)(?=.*\b(nbc|reality|episode|show|watch|series|season|premiere)\b).*
(?s) # Dot all modifier
^ # Beginning of string
(?= # Look ahead
.* # Greedy, any number of characters
\b bear\ grylls \b # Must be 'bear grylls'
) # End lookahead
(?= # Look ahead
.* # Greedy, any number of characters
\b
( # (1 start), Must be one of these
nbc
| reality
| episode
| show
| watch
| series
| season
| premiere
) # (1 end)
\b
) # End lookahead
.* # Assertions passed tests, now match the entire string
我建议使用RegexFormat 5格式化并创建自动评论。
答案 1 :(得分:0)
所有前瞻和后瞻断言(?=...)
,(?!...)
,(?<=...)
,(?<!...)
不会使用文字。它不会将指针前进到当前位置,这是匹配某些文本时的正常行为。
由于它不会使索引前进,因此您可以使用此属性来检查文本的多个属性,否则很难将它们组合成单个表达式而不进行预读。
在你的情况下,正则表达式检查是否存在字符串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个正则表达式并测试每个字符串。性能大致相同,因为在正则表达式引擎中完成了相同的工作量。事实上,我相信大多数引擎会在上面的正则表达式中重新扫描字符串两次。
答案 2 :(得分:0)
我重写了你的原始正则表达式,它可以得到你想要的结果
^(?=.*?bear grylls).+(?=.*?(\bnbc\b|reality|episode|show|watch|series|season|premiere)).*?
它与前一个非常相似。唯一的区别是我添加&#34;。+&#34;在两个积极的先行断言之间,这将强制执行这两个部分的顺序,例如,&#34;承担grylls剧集&#34;将会有积极的结果,而#34;情节会伴随着#34;韩元&#39;吨。
如果没有这个,这两个前瞻断言不会有任何序列偏好。基本上他们是完全平等的。