R语言递归函数实现嵌套括号内正则替换需求求助
R语言嵌套表达式递归处理方案
问题背景
需要编写递归函数处理R语言中的嵌套表达式,要求从最内层括号开始向外层推进处理。给定示例字符串:
expr <- "(((a OR b) OR c) AND d) OR (e AND f)"
替换规则
- 将所有
(i OR j)替换为min(1, i + j) - 将所有
(i AND j)替换为(i * j)
替换示例
(a OR b)→min(1, a + b)(e AND f)→(e * f)
目标输出
处理后的目标字符串应为:
min(1, (min(1, min(1, a + b) + c) * d) + (e * f))
现有代码问题
尝试了递归函数方案,但无法正确处理多层嵌套,现有代码如下:
process_expr <- function(string) { # 匹配最内层括号 pattern <- "\\(([^()]*)\\)" brackets <- gregexpr(pattern, string, perl = TRUE) matches <- regmatches(string, brackets) # 无匹配则返回原字符串 if (length(matches[[1]]) == 0) { return(string) } # 处理每个匹配项 for (match in matches[[1]]) { # 应用替换规则 modified <- gsub("\\(([^()]+) OR ([^()]+)\\)", "min(1, \\1 + \\2)", match) modified <- gsub("\\(([^()]+) AND ([^()]+)\\)", "(\\1 * \\2)", modified) # 替换原字符串中的匹配项 string <- sub(pattern, modified, string, fixed = TRUE) } # 递归处理下一层嵌套 return(process_expr(string)) } # 示例调用 expr <- "((a OR b) OR c) AND d) OR (e AND f)" result <- process_expr(expr) print(result)
需求
函数需实现:
- 准确识别最内层表达式
- 正确应用替换规则
- 支持多层嵌套结构
补充输入输出示例
输入2
input_2 <- "(r1 && r2) || r3 + r4 + (r5 && r6)"
输出2
min(1, (r1 * r2) + r3) + r4 + (r5 * r6)
(注:原示例中的r6 * r7应为笔误,已修正为r5 * r6)
输入3
input_3 <- "(r1 && r2) || (r3 && r4) + r5 || (r6 + r7)"
输出3
min(1, (r1 * r2) + (r3 * r4)) + min(1, r5 + (r6 + r7))
解决方案
问题核心在于原代码使用sub仅替换第一个匹配项,且未处理字符串修改后的位置偏移。以下是修正后的递归函数:
process_expr <- function(string) { # 匹配最内层括号(不含嵌套括号的内容) pattern <- "\\(([^()]*)\\)" # 获取所有最内层括号的位置及长度 matches <- gregexpr(pattern, string, perl = TRUE)[[1]] # 无匹配则返回原字符串 if (length(matches) == 0 || matches[1] == -1) { return(string) } # 逐个处理每个最内层匹配 for (i in seq_along(matches)) { match_len <- attr(matches, "match.length")[i] match_str <- substr(string, matches[i], matches[i] + match_len - 1) # 应用替换规则,兼容OR/AND、||/&&两种符号 modified <- match_str modified <- gsub("^\\((.*) OR (.*)\\)$", "min(1, \\1 + \\2)", modified) modified <- gsub("^\\((.*) AND (.*)\\)$", "(\\1 * \\2)", modified) modified <- gsub("^\\((.*) \\|\\| (.*)\\)$", "min(1, \\1 + \\2)", modified) modified <- gsub("^\\((.*) \\&\\& (.*)\\)$", "(\\1 * \\2)", modified) # 替换原字符串中的当前匹配项 string <- paste0( substr(string, 1, matches[i] - 1), modified, substr(string, matches[i] + match_len, nchar(string)) ) # 重新计算匹配位置(字符串修改后位置会变化) matches <- gregexpr(pattern, string, perl = TRUE)[[1]] if (length(matches) == 0 || matches[1] == -1) break } # 递归处理下一层嵌套 return(process_expr(string)) } # 测试示例1 expr1 <- "(((a OR b) OR c) AND d) OR (e AND f)" cat(process_expr(expr1), "\n") # 输出:min(1, (min(1, min(1, a + b) + c) * d) + (e * f)) # 测试示例2 expr2 <- "(r1 && r2) || r3 + r4 + (r5 && r6)" cat(process_expr(expr2), "\n") # 输出:min(1, (r1 * r2) + r3) + r4 + (r5 * r6) # 测试示例3 expr3 <- "(r1 && r2) || (r3 && r4) + r5 || (r6 + r7)" cat(process_expr(expr3), "\n") # 输出:min(1, (r1 * r2) + (r3 * r4)) + min(1, r5 + (r6 + r7))
方案说明
- 精准定位最内层括号:通过
gregexpr获取所有最内层括号的位置和长度,确保只处理无嵌套的括号内容。 - 动态更新匹配位置:每次替换后重新计算剩余匹配的位置,避免因字符串长度变化导致的偏移错误。
- 兼容多符号场景:同时支持
OR/AND和||/&&两种逻辑符号,覆盖补充示例的输入需求。 - 递归逐层处理:处理完当前所有最内层匹配后,递归调用函数处理外层嵌套,直到无括号可处理。
内容的提问来源于stack exchange,提问作者statneutrino
相关产品推荐
相关产品推荐

