これが私がそれを行う方法です:
keyword <- "moon"
lookaround <- 2
pattern <- paste0("([[:alpha:]]+ ){0,", lookaround, "}", keyword,
"( [[:alpha:]]+){0,", lookaround, "}")
regmatches(str, regexpr(pattern, str))[[1]]
# [1] "The cow jumped over"
アイデア:任意の文字を検索し、その後に最小で 0 回、最大で "lookaround" (ここでは 2 回) 発生するスペースが続き、その後に "keyword" (ここでは "moon") が続き、その後にスペースと一連の文字列が続きます。 0 から "lookaround" 回の間で繰り返される文字パターン。このregexpr
関数は、このパターンの開始と停止を提供します。regmatches
この関数をラップしてから、この開始/停止位置から部分文字列をフェッチします。
注:同じパターンの複数の出現を検索する場合regexpr
は、 に置き換えることができます。gregexpr
Hongの回答と比較したビッグデータのベンチマークは次のとおりです。
str <- "The cow jumped over the moon with a silver plate in its mouth"
ll <- rep(str, 1e5)
hong <- function(str) {
str <- strsplit(str, " ")
sapply(str, function(y) {
i <- which(y=="moon")
paste(y[seq(max(1, (i-2)), min((i+2), length(y)))], collapse= " ")
})
}
arun <- function(str) {
keyword <- "moon"
lookaround <- 2
pattern <- paste0("([[:alpha:]]+ ){0,", lookaround, "}", keyword,
"( [[:alpha:]]+){0,", lookaround, "}")
regmatches(str, regexpr(pattern, str))
}
require(microbenchmark)
microbenchmark(t1 <- hong(ll), t2 <- arun(ll), times=10)
# Unit: seconds
# expr min lq median uq max neval
# t1 <- hong(ll) 6.172986 6.384981 6.478317 6.654690 7.193329 10
# t2 <- arun(ll) 1.175950 1.192455 1.200674 1.227279 1.326755 10
identical(t1, t2) # [1] TRUE