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

时间:2014-05-29 21:55:16

标签: regex r

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

例如:

  1. 我喜欢苹果
  2. 我真的很喜欢苹果
  3. 我喜欢苹果和橘子
  4. 我希望得到第1和第2条。

    我怎么能用R来做呢?

    感谢。

3 个答案:

答案 0 :(得分:22)

可以做

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"

答案 1 :(得分:12)

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

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"

正则表达式向前看是否除了换行符和没有子串orange之外没有字符,如果是,那么点.将匹配除换行符之外的任何字符因为它被包裹在一个组中,并重复(0或更多次)。接下来,我们会查找apple以及换行符之外的任何字符(0或更多次)。最后,线锚的起点和终点都已到位,以确保输入被消耗。


更新:如果出现性能,则可以使用以下内容。

x[grepl('^(?!.*orange).*$', x, perl=TRUE)]

答案 2 :(得分:9)

这个正则表达式比其他正则表达式版本更小,更快(见下面的比较)。我没有与David的双grepl进行比较的工具,所以如果有人可以比较下面的单grep与我们能够知道的双grepl。必须对成功案例和失败案例进行比较。

^(?!.*orange).*apple.*$
  1. 否定前瞻确保我们没有orange
  2. 我们只匹配字符串,只要它包含apple即可。不需要前瞻。
  3. 代码示例

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

    速度比较

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

    1. 针对I like apples and oranges,引擎需要22个步骤才能失败,对于双前瞻版本^(?=.*apple)((?!orange).)*$需要143步,^((?!.*orange).)*apple.*$需要22步(等于等待第2点)。
    2. 针对I really like apples,引擎需要64步才能成功,而双前瞻版本^(?=.*apple)((?!orange).)*$需要104步,^((?!.*orange).)*apple.*$需要538步。
    3. 这些数字由RegexBuddy调试器提供。