Regex 包含和排除R中某些字符串的正则表达式

Regex 包含和排除R中某些字符串的正则表达式,regex,r,Regex,R,我正在尝试使用R来解析许多条目。我有两个要求的条目,我想回来。我想要所有包含单词apple但不包含单词orange的条目 例如: 我喜欢苹果 我真的很喜欢苹果 我喜欢苹果和桔子 我想拿回条目1和条目2 我怎么能用R来做这件事呢 谢谢。可以 temp <- c("I like apples", "I really like apples", "I like apples and oranges") temp[grepl("apple", temp) & !grepl("orange"

我正在尝试使用R来解析许多条目。我有两个要求的条目,我想回来。我想要所有包含单词
apple
但不包含单词
orange
的条目

例如:

  • 我喜欢苹果
  • 我真的很喜欢苹果
  • 我喜欢苹果和桔子
  • 我想拿回条目1和条目2

    我怎么能用R来做这件事呢

    谢谢。

    可以

    temp <- c("I like apples", "I really like apples", "I like apples and oranges")
    temp[grepl("apple", temp) & !grepl("orange", temp)]
    
    ## [1] "I like apples"      "I really like apples"
    

    temp使用正则表达式,可以执行以下操作

    x <- c('I like apples', 'I really like apples', 
           'I like apples and oranges', 'I like oranges and apples',
           'I really like oranges and apples but oranges more')
    
    x[grepl('^((?!.*orange).)*apple.*$', x, perl=TRUE)]
    # [1] "I like apples"        "I really like apples"
    

    这个正则表达式比其他正则表达式版本小一些,速度快得多(参见下面的比较)。我没有工具可以与David的double
    grepl
    进行比较,因此如果有人可以将下面的单
    grep
    与double
    grepl
    进行比较,我们就可以知道了。必须对成功案例和失败案例进行比较

    ^(?!.*orange).*apple.*$
    
  • 反向前瞻确保我们没有
    orange
  • 我们只需匹配字符串,只要它包含
    apple
    。没有必要在那里进行前瞻
  • 代码示例

    grep("^(?!.*orange).*apple.*$", subject, perl=TRUE, value=TRUE);
    
    速度比较

    @hwnd现在已经删除了双前瞻版本,但根据RegexBuddy,速度差异仍然存在:

  • 我喜欢苹果和橙子相比,引擎需要22个步骤才能失败,而双前瞻版本
    ^(?=.*apple)((?!orange)。*$
    ^((?!.*orange)。*apple.$
    需要22个步骤才能失败(这两个步骤相等,但等待第2点)
  • 相对于
    我真的很喜欢苹果
    ,该引擎需要64个步骤才能成功,而双前瞻版本
    ^(?=.*apple)((?!橙色)。*$
    需要104个步骤,
    ^((?!.*橙色)。*apple.*$
    需要538个步骤

  • 这些数字是由RegexBuddy调试器提供的。

    如果您添加一个解释,说明它是如何工作的,这将非常有用。@Arun这确实是一个棘手的问题。第一个子表达式询问,从第一个字符前的位置开始,是否有任何字符串后跟字符“apple”。如果找到一个,正则表达式引擎将返回到第一个字符之前的位置,并开始测试否定的先行断言。第二个子表达式是相对棘手的一个。它的工作原理是,在单词的每个字符间隔处检查是否有:(a)前面有一个字符,但(b)前面没有字符串“orange”。等价地,do
    grep(“^(?=.*apple)((?!orange)。*$”,x,perl=T,value=T)
    @JoshO'Brien,谢谢。我能够(某种程度上)理解它在做什么:),但不能像你那样解剖它。@Arun——我也有类似的反应。一开始我觉得它确实错了,但经过几分钟的尝试,我还是没能打破它。我很高兴我破解了它b/c这是一种可以像顽强的耳虫一样卡在我脑袋里的谜题!是的,这比我好得多,主要是因为它更容易摸索。@hwnd-Ha,你觉得自己像个令人难以置信的人,太棒了!。。。有时,我也会这样做,但这是一个错误(在一个直接匹配的地方留下一个前瞻)我要问乔希的下一个问题是速度。谢谢你的回答。@hwnd,为什么大卫的双格雷普比我的单格雷普快?我没有测试的工具,但这对我来说不是直观的。@tehAlgorithmist有一个ASNWER帮你解决了它,还是你还在努力解决它?请让我们知道。:)仅供参考,在我迟交的答案中添加了速度比较。顺便说一句,当我发布这个答案时,我惊讶于这个问题已经得到了如此多的关注(你和两个已经回答的人之间有24票!)你是著名演员还是什么的?:)我不确定性能等,但我认为这读起来比其他任何东西都清楚得多!特别是如果你必须排除几个词@drmariod将
    fixed=TRUE
    添加到两个
    grepl
    调用中,将使此解决方案成为一个非常有竞争力的解决方案。谢谢,阅读您的答案总是一件愉快的事!目前我只使用了几百个元素,但我会记住这一点!问了这个问题后,这个解决方案对我有效吗:,但其他解决方案无效
    grep("^(?!.*orange).*apple.*$", subject, perl=TRUE, value=TRUE);