Applying a function to a backreference within gsub in R

后端 未结 4 1356
被撕碎了的回忆
被撕碎了的回忆 2020-12-03 23:19

I\'m new to R and am stuck with backreferencing that doesn\'t seem to work. In:

gsub(\"\\\\((\\\\d+)\\\\)\", f(\"\\\\1\"), string)

It corre

4条回答
  •  醉话见心
    2020-12-04 00:04

    Here's a way by tweaking a bit stringr::str_replace(), in the replace argument, just use a lambda formula as the replace argument, and reference the captured group not by ""\\1" but by ..1, so your gsub("\\((\\d+)\\)", f("\\1"), string) will become str_replace2(string, "\\((\\d+)\\)", ~f(..1)), or just str_replace2(string, "\\((\\d+)\\)", f) in this simple case :

    str_replace2 <- function(string, pattern, replacement, type.convert = TRUE){
      if(inherits(replacement, "formula"))
        replacement <- rlang::as_function(replacement)
      if(is.function(replacement)){
        grps_mat <- stringr::str_match(string, pattern)[,-1, drop = FALSE]
        grps_list <- lapply(seq_len(ncol(grps_mat)), function(i) grps_mat[,i])
        if(type.convert) {
          grps_list <- type.convert(grps_list, as.is = TRUE) 
          replacement <- rlang::exec(replacement, !!! grps_list)
          replacement <- as.character(replacement)
        } else {
          replacement <- rlang::exec(replacement, !!! grps_list)
        }
      }
      stringr::str_replace(string, pattern, replacement)
    }
    
    str_replace2(
      "foo (4)",
      "\\((\\d+)\\)", 
      sqrt)
    #> [1] "foo 2"
    
    str_replace2(
      "foo (4) (5)",
      "\\((\\d+)\\) \\((\\d+)\\)", 
      ~ sprintf("(%s)", ..1 * ..2))
    #> [1] "foo (20)"
    

    Created on 2020-01-24 by the reprex package (v0.3.0)

提交回复
热议问题