在R中替换字符串,给定模式向量和替换向量

3

如果有一个包含不同占位符的字符串需要替换,那么在 R 中是否有一种函数可以根据模式向量和替换向量替换所有占位符?

我已经用列表和循环完成了这个任务。

> library(stringr)    
> tt_ori <- 'I have [%VAR1%] and [%VAR2%]'
> tt_out <- tt_ori

> ttlist <- list('\\[%VAR1%\\]'="val-1", '\\[%VAR2%\\]'="val-2")
> ttlist
$`\\[%VAR1%\\]`
[1] "val-1"

$`\\[%VAR2%\\]`
[1] "val-2"

> for(var in names(ttlist)) {
+ print(paste0(var," -> ",ttlist[[var]]))
+ tt_out <- stringr::str_replace_all(string = tt_out, pattern =var, replacement = ttlist[[var]] )
+ }
[1] "\\[%VAR1%\\] -> val-1"
[1] "\\[%VAR2%\\] -> val-2"
> tt_out
[1] "I have val-1 and val-2"

有一个类似的问题R: gsub, pattern = vector and replacement = vector,但它要求用不同的模式替换不同的字符串。这里我想要在单个字符串中替换所有的模式。

我已经尝试过

> tt_ori <- 'I have VAR1 and VAR2'
> tt_out <- tt_ori
> ttdf <- data.frame(tt=c("VAR1", "VAR2"), val=c("val-1", "val-2"), stringsAsFactors = F)
> str(ttdf)
'data.frame':   2 obs. of  2 variables:
 $ tt : chr  "VAR1" "VAR2"
 $ val: chr  "val-1" "val-2"
> stringr::str_replace_all(string = tt_out, pattern =ttdf$tt, replacement = ttdf$val )
[1] "I have val-1 and VAR2" "I have VAR1 and val-2"

显然,输出不是我想要的(多个输出字符串,每个字符串仅有一个替换)。我在想是否有一个函数存在于基础库或众所周知的CRAN包中,可以像上面展示的那样被调用,并且能够在单个字符串中完成所有替换。你是否有更好的解决方案或建议我的循环或者应该将其转换为函数?[注]这些字符串可能是小型网页模板或配置文件。它们很小,因此对于10到20个替换而言,使用循环并不困难,但我正在寻找更优雅的解决方案。

еҰӮжһңжӮЁжңҹжңӣзҡ„иҫ“еҮәжҳҜеҹәдәҺиҫ“е…Ҙtt_oriзҡ„tt_outпјҢйӮЈд№Ҳmgsubеә”иҜҘдҪҝз”Ёmgsub(c('[%VAR1%]' , '[%VAR2%]'), c('val-1', 'val-2'), tt_ori)гҖӮ - akrun
@akrun,你是在谈论 qdap 中的 mgsub 吗?http://www.inside-r.org/packages/cran/qdap/docs/multigsub。我找到了这个链接https://dev59.com/HGUp5IYBdhLWcg3wdnh6,其中实现了一些 mgsub 函数。如果你把评论写成答案,我会接受它。 - Pablo Marin-Garcia
@akrun,你在之前的评论中使用的@符号指向了另一个Pablo;-) - Pablo Marin-Garcia
2个回答

1

尝试

library(qdap)
 mgsub(c('[%VAR1%]' , '[%VAR2%]'), c('val-1', 'val-2'), tt_ori)
#[1] "I have val-1 and val-2"

数据

 tt_ori <- 'I have [%VAR1%] and [%VAR2%]'

我以前没有尝试过mgsub,因为我没有安装qdap。我在这个评论中看到了这个函数https://dev59.com/rGIk5IYBdhLWcg3wRcQo#LqqgEYcBWogLw_1bErsC,但他们说它有很多依赖项,在答案https://dev59.com/rGIk5IYBdhLWcg3wRcQo#19426663中,他们将mgsub命令等效于`names(x1) <- mapply(gsub, a, b, names(x1))`,但这不是我想要的结果。 - Pablo Marin-Garcia
谢谢,我已经安装了qdap及其所有依赖项 > install.packages('qdap'),还安装了以下依赖项:‘data.table’、‘assertthat’、‘magrittr’、‘lazyeval’、‘openNLPdata’、‘qdapDictionaries’、‘qdapRegex’、‘qdapTools’、‘dplyr’、‘gender’、‘gridExtra’、‘igraph’、‘NLP’、‘openNLP’、‘reports’、‘stringdist’、‘tm’、‘venneuler’`,您的答案是正确的。 - Pablo Marin-Garcia
最后需要注意的是,mgsub在模式部分不需要转义方括号,而gsub需要。但另一方面,这意味着它无法接受正则表达式模式。我已经提出了一个关于如何将正则表达式传递给mgsub的新问题。http://stackoverflow.com/questions/28532172/r-qdapmgsub-how-to-pass-a-pattern-with-a-regular-expression - Pablo Marin-Garcia
1
@PabloMarin-Garcia 感谢您的评论。是的,它有很多依赖关系。您的新问题已经得到了答案 :-) - akrun
从源代码来看,我注意到mgsub是一个围绕着gsub的for循环。 - Karsten W.

0

这似乎可以达到你的需求。

tt_ori <- 'I have [%VAR1%] and [%VAR2%]'
patterns <- c('\\[%VAR1%\\]', '\\[%VAR2%\\]')
replacements <- c("val-1", "val-2")

stringr::str_replace_all(tt_ori, set_names(replacements, patterns))
# [1] "I have val-1 and val-2"

如果模式和替换的大小不匹配,即尝试用空字符串 "" 替换上面的所有 patterns,则无法工作。 - Ndharwood
1
@Ndharwood 如果您需要替换多个模式为空,可以使用 str_remove_all。类似这样 str_remove_all(tt_ori, paste(patterns, collapse = "|")) - Jakub.Novotny

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接