替换多个字符串中的多个单词

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_wordsmy_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"

由于所有河流和小溪出现的替换分别只是 RC,因此我们可以捕获每个可能匹配的第一个字母,然后使用这些字母的大写版本进行替换。

【讨论】:

我应该给出一个更详细的例子,在我的完整数据集中有 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"

【讨论】:

以上是关于替换多个字符串中的多个单词的主要内容,如果未能解决你的问题,请参考以下文章

使用nodejs替换文件中的多个字符串

选择多个用数组中的每个值替换一个单词

Python:用 re.sub 替换列表中的多个特定单词

用多个其他字符串替换多个字符串

Excel - 查找和替换多个单词

如何在python中用一个单词替换多个单词? [复制]