Вот еще вариант. Обратите внимание, что я ввел несколько слов перед вашим словом-маркером для извлечения, например, «Хозе», так как я предполагаю, что у вас будут не только предложения, начинающиеся с этого слова. Важной функциональностью является комбинация использования stri_locate
для определения конца слова-маркера, добавления одной позиции символа и использования этой позиции с последней позицией символа в вашей строке, которая будет передана в stri_sub
. Обратите внимание, что предоставленная функция не является отказоустойчивой, например, для случаев, когда нет совпадений и т. д.
Пожалуйста, также проверьте приведенные ниже тесты для трех предложенных решений.
library(stringi)
library(magrittr)
sentencas<- c("some words josé é um trabalhador responsável"
,"only one word José é um trabalhador responsável"
,"several words jose é um trabalhador responsável"
,"and again some words Jose é um trabalhador responsável")
stri_word <- function(marker, str, words_after_marker) {
stri_sub(str, cbind(stri_locate_first_coll(str, marker ,strength=1)[, "end"]+1, nchar(str)) ) %>%
{ gsub( "^\\s+|\\s+$", "", stri_extract_first_regex(., paste0("(\\s\\w+){", words_after_marker[1], ",", words_after_marker[2],"}"))) }
}
stri_word("jose", sentencas, c(1,3) )
#[1] "é um trabalhador" "é um trabalhador" "é um trabalhador" "é um trabalhador"
#Benchmarks
library(microbenchmark)
library(stringr)
stringi_positions <- function() {
stri_word <- function(marker, str, words_after_marker) {
stri_sub(str, cbind(stri_locate_first_coll(str, marker ,strength=1)[, "end"]+1, nchar(str)) ) %>%
{ gsub( "^\\s+|\\s+$", "", stri_extract_first_regex(., paste0("(\\s\\w+){", words_after_marker[1], ",", words_after_marker[2],"}"))) }
}
stri_word("jose", sentencas, c(1,3) )
}
stringi_map <- function() {
sentencas %>%
map(stri_extract_all_words) %>%
map(~{
.x <- flatten_chr(.x)
map(.x, stri_detect_coll, "jose", ignore.case=TRUE, strength=1L) %>%
flatten_lgl() %>%
which() -> pos
.x[(pos+1):(pos+1+3)]
})
}
semi_stringi <- function() {
sentencas %>%
stri_split_coll("jose ", strength=1, simplify = TRUE) %>%
.[,2] %>%
word(1,3)
}
microbenchmark(
stringi_map(),
semi_stringi(),
stringi_positions()
)
# Unit: microseconds
# expr min lq mean median uq max neval
# stringi_map() 3498.667 3752.886 4059.0339 4038.0925 4214.3480 7365.635 100
# semi_stringi() 485.543 558.966 805.0216 593.9015 652.7195 15806.567 100
# stringi_positions() 288.958 325.669 456.9946 344.6180 384.4865 10719.428 100
person
Manuel Bickel
schedule
13.11.2017