我正在尝试使用R来解析许多条目.我对我想要的条目有两个要求.我想要包含该单词apple但不包含该单词的所有条目orange.
例如:
我希望得到第1和第2条.
我怎么能用R来做这件事?
谢谢.
Dav*_*urg 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"
Run Code Online (Sandbox Code Playgroud)
hwn*_*wnd 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"
Run Code Online (Sandbox Code Playgroud)
正则表达式向前看是否除了换行符和没有子串之外没有任何字符orange,如果是这样,那么点将.匹配除换行符之外的任何字符,因为它包含在一个组中,并且重复(0或多次).接下来我们查找apple除了换行符之外的任何字符(0或更多次).最后,线锚的起点和终点到位,以确保消耗输入.
更新:如果性能有问题,您可以使用以下内容.
x[grepl('^(?!.*orange).*$', x, perl=TRUE)]
Run Code Online (Sandbox Code Playgroud)
这个正则表达式比其他正则表达式版本更小,更快(见下面的比较).我没有与大卫的双重比较的工具,grepl所以如果有人可以比较grep下面的单个和grepl我们能够知道的双重.必须对成功案例和失败案例进行比较.
^(?!.*orange).*apple.*$
Run Code Online (Sandbox Code Playgroud)
orangeapple.不需要在那里前瞻.代码示例
grep("^(?!.*orange).*apple.*$", subject, perl=TRUE, value=TRUE);
Run Code Online (Sandbox Code Playgroud)
速度比较
@hwnd现在已经删除了双重前瞻版本,但根据RegexBuddy,速度差异仍然存在:
I like apples and oranges,引擎需要22步才能失败,而双前瞻版本需要143 ^(?=.*apple)((?!orange).)*$步,而22步^((?!.*orange).)*apple.*$(相等于等待第2点).I really like apples,引擎需要64步才能成功,而双前瞻版本需要104 ^(?=.*apple)((?!orange).)*$步,而538步需要^((?!.*orange).)*apple.*$.这些数字由RegexBuddy调试器提供.