将含数字集合/范围的正则表达式向量转换为字符串向量
问题:展开正则表达式中的数字范围/集合为完整字符串向量
需求说明
我有一个包含数字集合或范围的正则表达式向量,想要把每个表达式转换成明确列出所有匹配项的字符串向量。
示例数据
x <- c("N17[0-3]", "438[46]", "I6[02-45]1", "V[1-3]71")
期望结果
"N170", "N171", "N172", "N173", "4384", "4386", "I601", "I621", "I631", "I641", "I651", "V171", "V271", "V371"
尝试的代码(无法实现需求)
x_split <- strsplit(x, "") lapply(x_split, function(y) { bracket1_idx <- which(y == "[") bracket2_idx <- which(y == "]") num1 <- y[bracket1_idx+1] num2 <- y[bracket2_idx-1] substr1 <- y[1:bracket1_idx-1] |> paste0(collapse="") if(bracket2_idx == length(y)) paste0(substr1, seq(num1, num2)) else { substr2 <- y[(bracket2_idx+1):length(y)] |> paste0(collapse="") paste0(substr1, seq(num1, num2), substr2) } })
解决方案
可以通过正则拆分字符串结构,解析括号内的数字规则生成所有可能的字符,再拼接成完整结果,代码实现如下:
library(stringr) expand_regex_num <- function(x) { # 拆分前缀、括号内数字规则、后缀 matches <- str_match(x, "^(.*?)\\[(.*?)\\](.*)$") prefix <- matches[, 2] num_part <- matches[, 3] suffix <- matches[, 4] # 解析括号内的数字规则,生成所有待替换的数字字符 expand_num_part <- function(part) { items <- str_split(part, ",")[[1]] nums <- c() for(item in items) { if(str_detect(item, "-")) { # 处理数字范围,保留原位数(比如02-05生成02/03/04/05) range <- str_split(item, "-")[[1]] start <- as.integer(range[1]) end <- as.integer(range[2]) nums <- c(nums, str_pad(seq(start, end), nchar(range[1]), pad = "0")) } else { # 处理单个数字 nums <- c(nums, item) } } nums } # 生成每个正则表达式对应的所有字符串 result_list <- lapply(1:length(x), function(i) { nums <- expand_num_part(num_part[i]) paste0(prefix[i], nums, suffix[i]) }) # 合并为单一向量 unlist(result_list) } # 测试运行 x <- c("N17[0-3]", "438[46]", "I6[02-45]1", "V[1-3]71") expand_regex_num(x)
运行后得到的结果与期望完全一致:
[1] "N170" "N171" "N172" "N173" "4384" "4386" "I601" "I621" "I631" "I641" "I651" "V171" "V271" "V371"
代码说明
- 用
str_match精准拆分每个字符串的前缀、括号内的数字规则段、后缀三部分; expand_num_part函数负责解析数字规则:区分单个数字和范围,对范围类规则保留原数字位数生成连续字符;- 最后将前缀、每个生成的数字字符、后缀拼接,合并所有结果。
内容的提问来源于stack exchange,提问作者nightstand
相关产品推荐
相关产品推荐

