我有以下代码,我希望给我一个包含 3 个元素的列表,因为 texts
中有 3 个元素:
library(stringr)
texts <- c("I doubt it! :)", ";) disagree, but ok.", "No emoticons here!!!")
smileys <- c(":)","(:",";)",":D")
str_extract_all(texts, fixed(smileys))
相反,我得到了四个列表(我的“模式”参数的长度,这里是笑脸
。此外,我还收到以下警告消息:
Warning message: In stri_extract_all_fixed(string, pattern, simplify = simplify, : longer object length is not a multiple of shorter object length```
嗯,我不认为长度会匹配,因为我正在寻找每个中任何表情的任何命中文本。这不像我想将字符串 1 与模式 1 匹配、字符串 2 与模式 2 匹配,等等。
意识到我搞乱了 stringi 对矢量化的理解,我尝试了这个:
texts %>% map(~ str_extract_all(.x, fixed(smileys)))
这要好得多,因为它给了我一个包含 3 个元素的列表,但每个元素又是一个包含四个元素的列表。
我想要得到的是一个尽可能少嵌套的 3 个列表。有人在某个地方解决了这个问题,但我一生都无法弄清楚或无法通过谷歌搜索它。我可以对此进行 for 循环,但我认为自己是 tidyverse 的公民......
感谢您的帮助。
最佳答案
您可以使用 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))
关于r - 具有固定(文字)字符的矢量化 stringr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41839195/