2017-01-24 10 views
2

У меня есть следующий код, который я ожидаю, чтобы дать мне список 3, так как есть 3 элемента в texts:Векторизованного stringr с фиксированными (буквенными) символами

library(stringr) 
texts <- c("I doubt it! :)", ";) disagree, but ok.", "No emoticons here!!!") 
smileys <- c(":)","(:",";)",":D") 
str_extract_all(texts, fixed(smileys)) 

Вместо этого, я получаю список из четырех (длина моего параметра «шаблон», то здесь smileys Кроме того, я получаю следующее предупреждение:.

предупреждение: В stri_extract_all_fixed (строка, шаблон, упрощать = упрощать,: больше объектов длина не кратна более короткому объектуlength```

Ну, я не думаю, длина будет матч, так как я ищу ни просмотров любой смайлов в каждом тексте. Это не так, как я хочу, чтобы соответствовать строку 1 с рисунком 1, строка 2 с узором 2 и т.д.

Зная, что я Мессинг понимание STRINGI по оцифровке, я попытался вместо этого:

texts %>% map(~ str_extract_all(.x, fixed(smileys))) 

Этот намного лучше, поскольку он дает мне список из 3, но каждый элемент, в свою очередь, представляет собой список из четырех.

То, что я пытаюсь получить, это список из 3, который настолько мал, насколько это возможно. Кто-то, где-то, решил это, но я не могу для жизни меня понять это или получить, как это сделать. Я мог бы сделать цикл за это, но считаю себя гражданином tidyverse ...

Благодарен за любую помощь.

+1

Не знакомы с 'stringr' , но я считаю, что вы можете взглянуть на [grep, используя вектор символов с несколькими шаблонами] (http://stackoverflow.com/questions/7597559/grep-using-a-character-vector-of-patterns). Если вы преследуете метод '' paste' 'collapse = |' ", вам может потребоваться рассмотреть [Как мне обрабатывать специальные символы, такие как \^$.? * | +() [{В моем регулярном выражении?] (Http : //stackoverflow.com/questions/27721008/how-do-i-deal-with-special-characters-like-in-my-regex) – Henrik

+0

Не уверен, что это то, что вы ищете, но можете попробовать что-то вроде этого: 'pattern <- paste (" \\ Q ", смайлики," \\ E ", sep =" ", collapse =" | "); stringi :: stri_extract_all_regex (тексты, паттерн) ' – Jota

+0

Да, вопрос просто вставлять вещи вместе с трубой заключается в том, что мне придется избегать всех круглых скобок, двоеточий и т. д., которые составляют много смайликов! – Joy

ответ

1

Вы можете использовать paste, чтобы обернуть каждый элемент smiley с \\Q и \\E и распада на регулярное выражение «или» метасимволом (|), чтобы сформировать единый шаблон. Как указано в документе link Henrik shared и задокументировано на ?regex и в руководстве stringi символы от \\Q и \\E интерпретируются буквально.

pattern <- paste("\\Q", smileys, "\\E", sep = "", collapse = "|") 
# [1] "\\Q:)\\E|\\Q(:\\E|\\Q;)\\E|\\Q:D\\E" 

library(stringi) 
stri_extract_all_regex(texts, pattern) 
#[[1]] 
#[1] ":)" 
# 
#[[2]] 
#[1] ";)" 
# 
#[[3]] 
#[1] NA 

Основание R:

regmatches(texts, gregexpr(pattern, texts)) 
#[[1]] 
#[1] ":)" 
# 
#[[2]] 
#[1] ";)" 
# 
#[[3]] 
#character(0) 
     # If you want an NA, instead of a zero-length vector, 
     # then you could do something like: 
     # lapply(
     # regmatches(texts, gregexpr(pattern, texts)), 
     # function(ii) ifelse(is.character(ii) & length(ii) == 0L, NA, ii)) 

И если вы хотите использовать purrr и избегать регулярных выражений, одна идея будет что-то вроде этого:

library(purrr) 
library(stringr) 
texts %>% 
    map(~ unlist(str_extract_all(.x, fixed(smileys)))) 
#[[1]] 
#[1] ":)" 
# 
#[[2]] 
#[1] ";)" 
# 
#[[3]] 
#character(0) 
     # if you want NA, not a zero-length vector, you could add: 
     # %>% map(~ ifelse(is.character(.x) & length(.x) == 0L, NA, .x))