如何在R语言中对字符串中q后的数字减1并替换原字符串?
问题:如何将字符串中q后的数字减1并替换原字符串?
我有一个长字符串,示例如下:
x <- "Text1 q10_1 text2 q17 text3 q22_5 ..."
希望将每个字母"q"后的数字减1,得到结果:
y <- "Text1 q9_1 text2 q16 text3 q21_5 ..."
我已经成功提取出所有数字:
numbers <- stringr::str_extract_all(x, "(?<=q)\\d+") numbers <- as.integer(numbers[[1]]) - 1
但尝试用新数字更新原字符串时未生效:
stringr::str_replace_all(x, "(?<=q)\\d+", as.character(numbers))
请问该如何解决?
解决方案
方法一:函数式替换(推荐)
str_replace_all支持传入函数作为替换值,直接在匹配过程中完成数字减1的操作,不需要提前提取数字,代码更简洁高效:
library(stringr) x <- "Text1 q10_1 text2 q17 text3 q22_5 ..." y <- str_replace_all(x, "(?<=q)\\d+", function(match) as.integer(match) - 1)
原理是每次匹配到q后的数字时,匿名函数会把匹配到的字符串转成整数减1,再自动转成字符串替换回原位置。
方法二:循环替换(兼容提前提取数字的场景)
如果坚持要用提前提取的数字列表替换,需要循环调用str_replace依次处理每个匹配项:
library(stringr) x <- "Text1 q10_1 text2 q17 text3 q22_5 ..." numbers <- as.integer(str_extract_all(x, "(?<=q)\\d+")[[1]]) - 1 y <- x for (i in seq_along(numbers)) { y <- str_replace(y, "(?<=q)\\d+", as.character(numbers[i])) }
注意这种方法在处理长字符串时效率不如函数式替换,因为每次循环都会重新扫描字符串找第一个匹配项。
内容的提问来源于stack exchange,提问作者drastega
相关产品推荐
相关产品推荐

