带有固定(文字)字符的矢量化字符串

时间:2017-01-24 21:20:09

标签: r string stringr tidyverse

我已经获得了以下代码,由于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个列表。某个地方的某个人已经解决了这个问题,但是我无法解决这个问题,或者知道如何去谷歌。我可以为此做一个循环,但我认为自己是整齐的公民......

感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

您可以使用pastesmiley的每个元素与\\Q\\E包装在一起,然后折叠在正则表达式“或”元字符(|)上形成一个单一的模式。正如link Henrik shared中所述并在?regexstringi手册中记录的那样,\\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))