使用正则表达式将列中的数字范围替换为单个数字的实现方案
问题:将文本列中的数字范围转换为单个数字或展开序列
给定如下R数据:
Seeds<-c("Seeds.jpg 1-7-Sunflower[seeds 1-7.jpg]", "Seeds.jpg 8-Sunflower[seeds 8.jpg]", "Seeds.jpg 9-15-Sunflower[seeds 9-15.jpg]") Pot<-c("1.jpg-Sunflower[1.jpg]", "2.jpg-Sunflower[2.jpg]", "3.jpg-Sunflower[3.jpg]", "4.jpg-Sunflower[4.jpg]", "5.jpg-Sunflower[5.jpg]", "6.jpg-Sunflower[6.jpg]", "7.jpg-Sunflower[7.jpg]", "8.jpg-Sunflower[8.jpg]", "9.jpg-Sunflower[9.jpg]", "10.jpg-Sunflower[10.jpg]", "11.jpg-Sunflower[11.jpg]", "12.jpg-Sunflower[12.jpg]", "13.jpg-Sunflower[13.jpg]", "14.jpg-Sunflower[14.jpg]", "15.jpg-Sunflower[15.jpg]") Garden<-data.frame(Pot,Seeds)
需要生成新列Seeds2,支持两种格式:
- 将数字范围展开为单独行,每行对应一个数字
- 将数字范围替换为逗号分隔的数字序列
方案1:展开范围为单独行
使用stringr提取数字范围,结合tibble和tidyr::unnest生成展开后的行,再替换文本中的范围为单个数字:
library(tidyverse) Garden_expanded <- Garden %>% # 提取起始和结束数字,兼容单个数字的情况 mutate( num_range = str_extract(Seeds, "\\d+-\\d+|\\d+"), start = as.integer(str_split(num_range, "-", simplify = TRUE)[,1]), end = as.integer(str_replace_na(str_split(num_range, "-", simplify = TRUE)[,2], start)) ) %>% # 生成每个数字的序列 mutate(num = map2(start, end, seq.int)) %>% # 展开为单独行 unnest(num) %>% # 替换Seeds中的数字范围为当前num mutate( Seeds2 = str_replace_all(Seeds, "\\d+-\\d+|\\d+", as.character(num)), # 可选:匹配示例中seed/seeds的交替格式,不需要可删除此行 Seeds2 = if_else(num %% 2 == 1, str_replace(Seeds2, "seeds", "seed"), Seeds2) ) %>% # 移除中间辅助列 select(Pot, Seeds, Seeds2) # 查看结果 print(Garden_expanded$Seeds2)
方案2:将范围替换为逗号分隔序列
直接提取范围后生成逗号分隔的字符串,替换原文本中的范围:
library(stringr) Garden$Seeds2 <- sapply(Garden$Seeds, function(x) { # 提取数字范围 num_range <- str_extract(x, "\\d+-\\d+|\\d+") if (str_detect(num_range, "-")) { # 拆分起始和结束数字 nums <- as.integer(str_split(num_range, "-")[[1]]) # 生成逗号分隔的序列 num_seq <- paste(seq.int(nums[1], nums[2]), collapse = ",") # 替换原范围 str_replace_all(x, "\\d+-\\d+", num_seq) } else { # 单个数字直接返回原字符串 x } }) # 查看结果 print(Garden$Seeds2)
内容的提问来源于stack exchange,提问作者Zard22
相关产品推荐
相关产品推荐

