在R中使用负前瞻的意外行为

时间:2015-04-17 01:50:05

标签: regex r

快速提问:任何人都可以告诉我原因

grepl('p(?!q)', 'pq', perl = TRUE)

FALSE

但是

grepl('p(?!p)', 'pp', perl = TRUE)

TRUE

不应该使用完全相同的逻辑吗?如何使用负前瞻来匹配包含" p"的字符串?那不是另一个" p"?

2 个答案:

答案 0 :(得分:5)

grepl('p(?!q)', 'pq', perl = TRUE)

此处只有一个p,因此它仅检查单个p。检查单个p后面没有q。但它失败了,p后跟q。由于找不到匹配项,因此返回FALSE

grepl('p(?!p)', 'pp', perl = TRUE)

这里检查第一个p。它失败了,因为第一个p后跟另一个p。但是当它检查第二个p时,条件变为真,因为第二个p后面没有p。因为它找到至少一个匹配项,所以返回TRUE

答案 1 :(得分:3)

不,因为(?!p)因为字符串位置的结束而仍然匹配。要纠正先行,你需要断言“p”或字符串末尾的位置都不会出现。

grepl('p(?!p|$)', 'pp', perl = TRUE)
# [1] FALSE

这里也不需要Lookahead,你可以使用一个否定的字符类:

grepl('p[^p]', c('pp', 'ppp', 'pq'))
# [1] FALSE FALSE  TRUE

相同的逻辑不允许“q”跟随:

grepl('p[^q]', c('pp', 'ppp', 'pq'))
# [1]  TRUE  TRUE FALSE