【问题标题】:Unexpected result of negative lookahead on word (R regex)单词负前瞻的意外结果(R 正则表达式)
【发布时间】:2016-04-26 16:14:30
【问题描述】:

我正在尝试为包含“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|$)")

这三个方法都返回 true。

【问题讨论】:

  • 您意识到cat.*[^dog] 将在字符串cat foobarbaz godcat foobarbaz odg 等上失败。原因是[^] 将匹配任何字符,但那些里面,除了里面的那个以外没有任何词
  • 此外,它们应该返回 true。原因是如果 Negative Lookahead 匹配,它们将是真的。如果您希望它们是假的,只需删除否定并使其成为正常组。
  • @ Druzion,你的意思是grepl("cat.*(?=dog)", "asdfasdfasdf cat adsfafds dog", perl=T) ?好吧,这只是返回 true,因为它正在检查字符串中是否有 cat 和 dog。
  • 没有。这是一个积极的前瞻,它将检查狗是否存在。使用负前瞻:cat.*(?!dog)。我知道你已经这样做了,我只是想指出为什么第一种方法行不通。

标签: regex r


【解决方案1】:

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

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

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


所有解决方案的问题是cat.* 会找到cat,然后.* 会吃掉所有东西,包括dogs。

另外,你忘了处理狗先于猫的情况。

正如 Druzion 指出的那样,char 类不是要走的路。

【讨论】:

  • 这是一条相当复杂的线,但似乎适用于我的特定目的。我现在正在剖析它。
  • 您的解决方案的第二部分似乎让我们到达了我们需要的地方:grepl("^(((?!dog).)*?cat((?!dog).)*)+$", "dog cat asdfadsfad", perl=T) 让我们到达了我们需要的地方
  • 为什么我们需要该行中的 ^ 和 $ 锚点。根据您提供的链接,这是为了确保整个输入都是消费者。如果没有锚点,正则表达式会如何表现?
  • @matsuo_basho 尝试将它与catdogcatdog 匹配,有无锚点,你会看到。 :)
  • @matsuo_basho 没有锚,它可以找到匹配的子字符串。您可以使用regex101.com 进行可视化。
【解决方案2】:

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

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

【讨论】:

  • 刚刚注意到这条线的某些内容不符合我的目的。我用“狗”和“猫”作为特定词来表达这个问题。但是,我当然需要这是动态的。问题是,如果我们在字符串中既没有“狗”也没有“猫”而是其他术语,上述脚本仍然会产生 true。例如“asdfadsf giraffe adsfa gorilla”将返回 true,因为在字符串中找不到这些词。
  • @matsuo_basho 好的,我误解了最后一部分。我认为如果既没有猫也没有狗,那么它也会被接受
  • 我真的很喜欢你的解决方案,因为它非常优雅.....也许对其进行修改仍然可以实现我的目标。
  • @matsuo_basho 抱歉回复晚了..更新了代码..不是最好的..但它会解决问题..你可以说这也可以在没有正则表达式的情况下完成
猜你喜欢
  • 2022-09-29
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
  • 2011-10-14
  • 2010-12-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多