单词上的负前瞻(R regex)的意外结果

时间:2016-04-26 16:14:31

标签: regex r

我正在尝试为包含“dog”但不包含“cat”的句子创建规则。我希望函数返回FALSE,因为字符串包含“dog”和“cat”。

使用否定:

grepl("cat.*[^dog]", "asdfasdfasdf cat adsfafds dog", perl=T)

使用否定前瞻:

grepl("cat.*(?!dog)", "asdfasdfasdf cat adsfafds dog", perl=T)

在stringr包中使用str_detect函数

require(stringr)
str_detect("asdfasdfasdf cat adsfafds dog", "cat.*(?!dog|$)")

所有这三种方法都归结为真。

2 个答案:

答案 0 :(得分:1)

您可以使用此正则表达式查找包含cat但不包含dog的字符串:

^((cat((?!dog).)*)|(((?!dog).)*?cat((?!dog).)*)+)$

这是基于答案here。考虑到狗可以在猫之前或之后来。

您的所有解决方案的问题是,cat.*会找到cat,然后.*会吃掉所有内容,包括dog s。

另外,你忘了处理狗在猫之前来的情况。

正如Druzion指出的那样,char课程不是可行的方法。

答案 1 :(得分:1)

一个简单的解决方案是创建一个检查函数: -

  

i)如果字符串包含catdog,则返回FALSE

     

ii)否则,返回TRUE

R代码

cat_dog <- function(x) { if (length(grep("(?=.*cat)(?=.*dog)", x, perl = TRUE)) != 0) {return(FALSE)} else {return(TRUE)} }

更新了代码

cat_dog <- function(x) { if (length(grep("(?=.*dog)", x, perl = TRUE) != 0)) {if (length(grep("(?=.*cat)", x, perl = TRUE)) != 0) {return(FALSE)} else {return(TRUE)}} else {return(FALSE)}}

<强> Ideone Demo