在字符向量和 window 函数的每个项目中搜索参数模式的匹配项

Search for matches to argument pattern within every item of a character vector and a window function

我有以下字符串

library(stringi)
s=stri_rand_lipsum(10)

函数 grepl 在字符向量的每个项目中搜索参数模式的匹配项。据我所知,它一次只搜索一个词。例如,如果我想搜索“conubia”和“viverra”,我必须执行两次搜索:

x=s[grepl("conubia",s)]
x=x[grepl("viverra",x)]

无论如何,我想搜索出现在 s 同一条目中的两个或多个术语,长度等于 window,例如140 个字符。

您可以使用 *apply 家庭。如果你的源文本是一个字符向量,我推荐使用vapply,但是你必须指定返回值的类型和长度。因为你使用了grepl,返回值是逻辑向量。

txt = "My name is Abdur Rohman"
patt = c("na", "Ab","man", "om")

vapply(patt, function(x) grepl(x,txt), 
       FUN.VALUE = logical(length(txt)))
# na    Ab   man    om 
# TRUE  TRUE  TRUE FALSE 

因此,在您的示例中,您可以使用:

s = stri_rand_lipsum(10)
vapply(c("conubia","viverra"), function(x) grepl(x,s), 
       FUN.VALUE = logical(length(s))
#      conubia viverra
# [1,]    TRUE    TRUE
# [2,]   FALSE   FALSE
# [3,]    TRUE   FALSE
# [4,]   FALSE   FALSE
# [5,]   FALSE   FALSE
# [6,]   FALSE    TRUE
# [7,]   FALSE   FALSE
# [8,]   FALSE   FALSE
# [9,]   FALSE   FALSE
#[10,]   FALSE   FALSE

编辑以包含 140 个字符 window

至于创建长度为 140 个字符的限制 window 的要求,如您的评论中所述,满足要求的一种方法是提取两个目标字符串之间的所有字符,然后计算提取的字符数。小于等于140才满足要求

提取两个字符串之间的所有字符可以通过gsub中的正则表达式来完成。但是,如果字符串重复,则需要指定 window。让我举个例子:

txt <- "Lorem conubia amet conubia ipsum dolor sit amet, finibus torquent diam lobortis dolor ac eget viverra dolor viverra"

此文本包含两个 conubia 和两个 viverra。您有四个选项可以选择 window 指定 all characters between conubia and viverra.

  1. 选项 1:在最后一个 conubia 和第一个 viverra
  2. 之间
gsub(".*conubia(.*?)viverra.*", "\1", txt, perl = TRUE)
#[1] " ipsum dolor sit amet, finibus torquent diam lobortis dolor ac eget "
  1. 选项 2:第一个 conubia 和最后一个 viverra
  2. 之间
gsub(".*?conubia(.*)viverra.*", "\1", txt, perl = TRUE)
# [1] " amet conubia ipsum dolor sit amet, finibus torquent diam lobortis dolor ac eget viverra dolor "
  1. 选项 3:第一个 conubia 和第一个 viverra
  2. 之间
gsub(".*?conubia(.*?)viverra.*", "\1", txt, perl = TRUE)
#[1] " amet conubia ipsum dolor sit amet, finibus torquent diam lobortis dolor ac eget "
  1. 选项 4:在最后一个 conubia 和最后一个 viverra
  2. 之间
gsub(".*conubia(.*)viverra.*", "\1", txt, perl = TRUE)
#[1] " ipsum dolor sit amet, finibus torquent diam lobortis dolor ac eget viverra dolor "

要计算提取的字符数,可以使用nchar

# Option 1
nchar(gsub(".*conubia(.*?)viverra.*", "\1", txt, perl = TRUE))
#[1] 68

应用此方法:

set.seed(8)
s1 <- stri_rand_lipsum(10)
Nch <- nchar(gsub(".*conubia(.*?)viverra.*", "\1", s1, perl = TRUE))
Nch
# [1] 637  42 512 528 595 640 522 407 388 512

我们发现s1的第二个元素符合要求。 要打印元素,我们可以使用:s1[which(Nch <= 140)].

我一直在学习的一些重要参考资料:

  1. https://www.buymeacoffee.com/wstribizew/extracting-text-two-strings-regular-expressions
  2. https://regex101.com/