Пример: в следующем примере я хочу добиться того, чтобы удалить все предложения, которые начинаются со слова «Генри», имеют слово «новый» в середине предложения и заканчиваются словом «ручка».

text = 'Henry just bought a new black pen. Henry\'s pen costs him $2. Henry buys a new blue pen.'

Что я сделал:

result = gsub(pattern='((Henry).*(new).*(pen))+',replacement='',text)

Чего я хочу добиться:

"Henry's pen costs him $2."

Чего я добился:

« »

Я не очень уверен, что пошло не так в моих кодах, кто-то может указать мне правильное направление?

0
OinkOink 29 Май 2017 в 05:56

2 ответа

Лучший ответ

Как подсказал @thelatemail, вы можете сначала разделить text на каждом ., чтобы получить вектор предложений, используя

strsplit(text, "(?<=\\.)\\s+", perl = TRUE)

Где шаблон "(?<=\\.)\\s+" означает, что мы разбиваем на необязательное пространство (\\s+) после . (утверждение позади (?<=\\.)). Как только мы это сделаем, мы сможем проверить каждое предложение на соответствие вашим критериям и отфильтровать те, которые не соответствуют. Тогда нам просто нужно снова вставить оставшиеся предложения вместе:

library(magrittr)
filteredText <- strsplit(text, "(?<=\\.)\\s+", perl = TRUE)[[1]] %>%
        grep(pattern = "^Henry.*new.*pen\\.$", x = ., value = TRUE, invert = TRUE) %>%
        paste(collapse = " ")
# 
filteredText
# [1] "Henry's pen costs him $2."
1
ikop 29 Май 2017 в 08:09

Вам нужно токенизировать по предложению. Вы можете аппроксимировать его, используя strsplit с sep = '\\.', но в качестве текста масштабируется сбой, например. не разделяя ? или разделяя U.S.A.. На данный момент, однако, использование гораздо лучшего токенайзера предложений совсем не сложно, благодаря tidytext, который удобно оборачивает пакет tokenizers в аккуратный каркас.

Вы можете либо разбить токены на предложения, а затем использовать регулярные выражения:

library(tidyverse)
library(tidytext)

text = 'Henry just bought a new black pen. Henry\'s pen costs him $2. Henry buys a new blue pen.'

data_frame(text) %>% 
    unnest_tokens(sentence, text, 'sentences', to_lower = FALSE) %>% 
    filter(!grepl('^Henry ', sentence), 
           !grepl('.new.{2,}', sentence),
           !grepl('pen.$', sentence))
#> # A tibble: 1 x 1
#>                    sentence
#>                       <chr>
#> 1 Henry's pen costs him $2.

... или заново сопоставьте слова, чтобы использовать более простые сравнения:

data_frame(text) %>% 
    unnest_tokens(sentence, text, 'sentences', to_lower = FALSE) %>% 
    unnest_tokens(word, sentence, drop = FALSE) %>% 
    group_by(sentence) %>% 
    filter(first(word) != 'henry',
           !'new' %in% word,
           last(word) != 'pen')
#> # A tibble: 5 x 2
#> # Groups:   sentence [1]
#>                    sentence    word
#>                       <chr>   <chr>
#> 1 Henry's pen costs him $2. henry's
#> 2 Henry's pen costs him $2.     pen
#> 3 Henry's pen costs him $2.   costs
#> 4 Henry's pen costs him $2.     him
#> 5 Henry's pen costs him $2.       2
0
alistaire 29 Май 2017 в 05:20