【问题标题】:Vectorized stringr with fixed (literal) characters具有固定(文字)字符的向量化字符串
【发布时间】:2017-06-09 21:38:22
【问题描述】:

我有以下代码,我希望给我一个包含 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))

相反,我得到了四个列表(我的“模式”参数的长度,这里是 smileys。此外,我收到以下警告消息:

警告信息:在 stri_extract_all_fixed(string, pattern, simple = 简化,:较长的对象长度不是较短对象的倍数 长度```

好吧,我不认为长度匹配,因为我正在寻找任何点击每个中任何的笑脸文本。这不像我想将字符串 1 与模式 1 匹配,将字符串 2 与模式 2 匹配,等等。

我知道我弄乱了 stringi 对矢量化的理解,所以我尝试了这个:

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

这要好得多,因为它给了我一个 3 的列表,但每个元素又是一个 4 的列表。

我想要的是一个尽可能少嵌套的 3 个列表。某个地方的某个人已经解决了这个问题,但我终其一生都无法弄清楚或无法通过谷歌搜索它。我可以为此做一个 for 循环,但我认为自己是 tidyverse 的公民......

感谢您的帮助。

【问题讨论】:

  • 不熟悉stringr,但相信你可能看过grep using a character vector with multiple patterns。如果你追求“pastecollapse = |”的方法,那么你可能需要考虑How do I deal with special characters like \^$.?*|+()[{ in my regex?
  • 不确定这是否是您要查找的内容,但您可以尝试以下方法:pattern &lt;- paste("\\Q", smileys, "\\E", sep = "", collapse = "|"); stringi::stri_extract_all_regex(texts, pattern)
  • 是的,只是用管道将东西粘贴在一起的问题是我必须转义所有构成很多笑脸的括号、冒号等!
  • 有罪,@Jota!在评论之前我没有尝试过。您的解决方案就像一个魅力!随意将其发布为答案,我会将其标记为正确。
  • @Joy Q/E 方法在我提供的第二个链接中描述。

标签: r string stringr tidyverse


【解决方案1】:

您可以使用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))

【讨论】:

    猜你喜欢
    • 2021-11-13
    • 1970-01-01
    • 2018-07-27
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    • 2018-08-27
    • 1970-01-01
    • 2012-09-05
    相关资源
    最近更新 更多