R语言 通过正则表达式根据字符串中的位置替换子字符串

ghhkc1vu  于 2023-09-27  发布在  其他
关注(0)|答案(4)|浏览(106)

让我们假设我的字符串中有一个特定的模式,它出现了已知的次数(n),我们不想对字符串的其余部分(特别是介于这些模式之间的字符串)做任何假设。
此外,我有一个长度为n(比如说sf)的向量,我想用相应的元素来修改模式的每次出现。因此,对于每一场比赛,我想知道多久一次比赛已经击中?
我可以想到以下解决方案:

library(stringr)
sf <- letters[4:1]
ss <- "fdskjhf xx sd ss xx wwwe xx ss  xx sdsd"
#              ^^ 1st   ^^ 2nd  ^^ 3rd ^^ 4th
# add:         _sf[1]   _sf[2]  _sf[3] _sf[4]
# that is:     xx_d     xx_c    xx_b   xx_a

## add _sf[i] to the ith occurence of "xx" in ss
goal <- "fdskjhf xx_d sd ss xx_c wwwe xx_b ss  xx_a sdsd"

my_replacer_factory <- function(sf, start = 0) {
  cnt <- start
  function(el) {
    cnt <<- cnt + 1
    paste0(el, "_", rev(sf)[cnt])
  }
}

my_replacer <- my_replacer_factory(sf)
(res <- str_replace_all(ss, fixed("xx"), my_replacer))
# [1] "fdskjhf xx_d sd ss xx_c wwwe xx_b ss  xx_a sdsd"

all.equal(res, goal)
# [1] TRUE

这显然是有效的,但感觉容易出错b/c我依赖于str_replace_all从右边开始替换的事实。如果在未来的实现中,这种行为发生了变化或被并行化了,那该怎么办?
有没有什么想法来实现这一点不同?理想情况下使用stringr函数?
类似的想法:

my_replacer_factory <- function(sf) {
  suffixes <- rev(sf)
  function(el) {
    on.exit(suffixes <<- suffixes[-1L], add = TRUE)
    paste0(el, "_", suffixes[1L])
  }
}
kg7wmglp

kg7wmglp1#

一种方法是使用regmatches<-

sf <- letters[4:1]
ss <- "fdskjhf xx sd ss xx wwwe xx ss  xx sdsd"

regmatches(ss, gregexpr("xx", ss)) <- list(paste0("xx_", sf))
ss
#[1] "fdskjhf xx_d sd ss xx_c wwwe xx_b ss  xx_a sdsd"

#Alternative with look behind
regmatches(ss, gregexpr("(?<=xx)", ss, perl=TRUE)) <- list(paste0("_", sf))
ibrsph3r

ibrsph3r2#

你可以使用strsplit在R中编写自己的stringr风格的函数:

str_replace_multi <- function(string, replace, replace_with) {
  sapply(strsplit(string, replace, fixed = TRUE), function(x) {
    paste0(paste0(head(x, -1), replace_with, collapse = ''), tail(x, 1))
  })
}

这允许:

str_replace_multi(ss, 'xx', paste0('xx_', sf))
#> [1] "fdskjhf xx_d sd ss xx_c wwwe xx_b ss  xx_a sdsd"

它将在string上进行向量化,这样您就可以在向量中的多个字符串中替换多个目标。

m1m5dgzv

m1m5dgzv3#

gsubfn-package使这里的事情变得更简单

# install.packages("gsubfn")
library(gsubfn)
p <- proto(fun = function(this, x) paste0(x, "_", count))
gsubfn("xx", p, ss)
[1] "fdskjhf xx_1 sd ss xx_2 wwwe xx_3 ss  xx_4 sdsd"

以获得所需的输出:

p <- proto(fun = function(this, x) paste0(x, "_", letters[stringr::str_count(ss, "xx") + 1 - count]))
gsubfn("xx", p, ss)
[1] "fdskjhf xx_d sd ss xx_c wwwe xx_b ss  xx_a sdsd"
f87krz0w

f87krz0w4#

paste0(grep(

paste0(grep('xx', unlist(strsplit(ss, ' ')), value = TRUE, fixed = TRUE), '_', sf[1:4])
[1] "xx_d" "xx_c" "xx_b" "xx_a"

相关问题