也许有点蛮力,但是...
s <- c("123(11)56(10)89")
int1 <- lapply(regmatches(s, gregexpr("\\([0-9]+\\)", s)),
function(z) as.integer(gsub(z, pattern = "\\D", replacement = "")))
int2 <- lapply(strsplit(sapply(regmatches(s, gregexpr("[^(0-9][0-9]+\\D?|\\D?[0-9]+[^)0-9]", s)),
function(z) paste(gsub("\\D", "", z), collapse = "")), ""), as.integer)
int1
# [[1]]
# [1] 11 10
int2
# [[1]]
# [1] 1 2 3 5 6 8 9
然后你可以总结它们
mapply(sum, int1, int2)
# [1] 55
我将它们保留为 lists 的原因是,它可以应用于字符串向量和索引中保留的总和。
编辑
这可以通过在基础 R 中使用 GuedesBF 的正则表达式来简化为单个表达式。不要接受我基于此的答案(该答案完成了大部分工作),但在基础 R 中这同样有效:
lapply(regmatches(s, gregexpr("\\(\\d{2}\\)|\\d", s)),
function(z) as.integer(gsub("\\D", "", z)))
# [[1]]
# [1] 1 2 3 11 5 6 10 8 9
如果你想要的只是求和而不看到这个向量,那么
sapply(regmatches(txt, gregexpr("\\(\\d{2}\\)|\\d", txt)),
function(z) sum(as.integer(gsub("\\D", "", z))))
# [1] 55
确实,GuedesBF 得到了正确的正则表达式,你应该接受这个答案。此答案提供的唯一优势是:
-
Base R,以防这对您很重要。
-
这个答案独立地处理每个字符串,所以如果length(s) 大于 1,这个答案仍然可以使用 GuedesBF 的正则表达式。
s3 <- rep(s, 3)
sapply(regmatches(s3, gregexpr("\\(\\d{2}\\)|\\d", s3)),
function(z) sum(as.integer(gsub("\\D", "", z))))
# [1] 55 55 55
...但这可以通过lapply 或purrr::map 或类似的东西轻松解决。