我正在尝试使用R来解析许多条目。我对我想要的条目有两个要求。我想要包含单词apple
的所有条目,但不要包含单词orange
。
例如:
我希望得到第1和第2条。
我怎么能用R来做呢?
感谢。
答案 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.*$
orange
apple
即可。不需要前瞻。代码示例
grep("^(?!.*orange).*apple.*$", subject, perl=TRUE, value=TRUE);
速度比较
@hwnd现在已经删除了这个双前瞻版本,但根据RegexBuddy,速度差异仍然存在:
I like apples and oranges
,引擎需要22个步骤才能失败,对于双前瞻版本^(?=.*apple)((?!orange).)*$
需要143步,^((?!.*orange).)*apple.*$
需要22步(等于等待第2点)。 I really like apples
,引擎需要64步才能成功,而双前瞻版本^(?=.*apple)((?!orange).)*$
需要104步,^((?!.*orange).)*apple.*$
需要538步。这些数字由RegexBuddy调试器提供。