替换多个字符串中的多个单词
Posted
技术标签:
【中文标题】替换多个字符串中的多个单词【英文标题】:Replace multiple words in multiple strings 【发布时间】:2022-01-17 11:52:43 【问题描述】:我想根据另一个数据框中的原始单词和替换单词替换向量中的单词。举个例子:
要更改的字符串向量:
my_words <- c("example r", "example River", "example R", "anthoer river",
"now a creek", "and another Ck", "example river tributary")
要替换的词的数据框和对应的替换词:
my_replace <- data.frame(
original = c("r", "River", "R", "river", "Ck", "creek", "Creek"),
replacement = c("R", "R", "R", 'R', "C", "C", "C"))
我想用向量my_words
中my_replace$replacement
中的相应值替换my_replace$original
中出现的任何单词。我尝试使用stringr::str_replace_all()
,但它替换了字母/单词的所有实例,而不是整个单词(例如“another”变成了“anotherR”),这是不可取的。
我想做的伪代码:
str_replace_all(my_words, my_replace$original, my_replace$replacement)
期望的输出:
"example R", "example R", "example R", "another R", "now a C", "and another C", "example R tributary"
我确实找到了使用for
循环的解决方案,但鉴于我的数据集很大,for
循环选项太慢了。非常感谢任何建议。
【问题讨论】:
【参考方案1】:这是一种sub
方法,它只进行一次替换:
my_words <- c("example r", "example River", "example R", "anthoer river",
"now a creek", "and another Ck", "example river tributary")
output <- gsub("\\b([rR])(?:iver)?\\b|\\b([cC])(?:ree)?k\\b", "\\U\\1\\U\\2", my_words, perl=TRUE)
output
[1] "example R" "example R" "example R"
[4] "anthoer R" "now a C" "and another C"
[7] "example R tributary"
由于所有河流和小溪出现的替换分别只是 R
和 C
,因此我们可以捕获每个可能匹配的第一个字母,然后使用这些字母的大写版本进行替换。
【讨论】:
我应该给出一个更详细的例子,在我的完整数据集中有 20-30 个其他替代替换代码,并且并非都是单个字母(例如,“pond”和“Pond”变成“Pnd”和“声音”和“声音”变成“Snd”)。所以我需要一个使用my_replace$replacement
. 中的值的解决方案,而不是依赖于删除部分单词。
@flee 对于 20-30 个其他目标匹配,您可以在我的答案中扩大交替以包括它们。【参考方案2】:
您需要从my_words$original
中的单词构建一个基于动态单词边界的模式,然后使用stringr::str_replace_all
替换为相应的值。注意original
短语需要按长度降序排序,以使较长的字符串首先匹配:
my_words <- c("example r", "example River", "example R", "anthoer river", "now a creek", "and another Ck", "example river tributary")
my_replace <- data.frame(original = c("r", "River", "R", "river", "Ck", "creek", "Creek"), replacement = c("R", "R", "R", 'R', "C", "C", "C"))
sort.by.length.desc <- function (v) v[order( -nchar(v)) ]
library(stringr)
regex <- paste0("\\b(",paste(sort.by.length.desc(my_replace$original), collapse="|"), ")\\b")
str_replace_all(my_words, regex, function(word) my_replace$replacement[my_replace$original==word][[1]][1])
输出:
[1] "example R" "example R" "example R" "anthoer R" "now a C" "and another C" "example R tributary"
正则表达式将是\b(River|river|creek|Creek|Ck|r|R)\b
,它将匹配里面的任何单词作为一个完整的单词。
【讨论】:
【参考方案3】:library(stringi)
stri_replace_all_regex(my_words, "\\b" %s+% my_replace$original %s+% "\\b", my_replace$replacement, vectorize_all = FALSE)
[1] "example R" "example R" "example R" "anthoer R" "now a C" "and another C" "example R tributary"
【讨论】:
以上是关于替换多个字符串中的多个单词的主要内容,如果未能解决你的问题,请参考以下文章