我已经获得了以下代码,由于texts
中有3个元素,因此我希望给出3个列表:
library(stringr)
texts <- c("I doubt it! :)", ";) disagree, but ok.", "No emoticons here!!!")
smileys <- c(":)","(:",";)",":D")
str_extract_all(texts, fixed(smileys))
相反,我得到一个四个列表(我的&#34;模式&#34;参数的长度,这里是smileys
。此外,我收到以下警告消息:
警告消息:在stri_extract_all_fixed中(字符串,模式,简化= 简化,:较长的对象长度不是较短对象的倍数 length```
好吧,我不会想象长度会匹配,因为我正在寻找任何点击任何的每个文字中的表情。它不像我想要将字符串1与模式1匹配,字符串2与模式2匹配等。
意识到我正在弄乱stringi对矢量化的理解,我试过这个:
texts %>% map(~ str_extract_all(.x, fixed(smileys)))
这要好得多,因为它给了我一个3的列表,但每个元素又是一个四个列表。
我想要的是一个尽可能少嵌套的3个列表。某个地方的某个人已经解决了这个问题,但是我无法解决这个问题,或者知道如何去谷歌。我可以为此做一个循环,但我认为自己是整齐的公民......
感谢任何帮助。
答案 0 :(得分:2)
您可以使用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))