如何用字符串中的数字向量替换值

how to replace values with a digital vector in a string

提问人:mr.T 提问时间:10/12/2023 最后编辑:zx8754mr.T 更新时间:10/12/2023 访问量:72

问:

我有一根绳子

str <- 'bool rule_cpp(int n, NumericVector x) {
  bool res = false;
  switch(n) {
    case 1: res = x[0] < x[4];  break;
    case 2: res = x[1] >= x[0]; break;
    case 3: res = x[3] == x[4]; break;
    case 1: res = x[0] != x[4]; break;
    case 2: res = x[1] >= x[0]; break;
    case 3: res = x[3] <= x[4]; break;
    case 1: res = x[0] < x[4];  break;
    case 2: res = x[1] >= x[0]; break;
    case 11: res = x[0] != x[4]; break;
    case 2: res = x[1] >= x[0]; break;
    case 3: res = x[3] <= x[4]; break;
    case 1: res = x[0] < x[4];  break;
    case 22: res = x[1] >= x[0]; break;
      default: stop("Invalid rule number");
  }
  return(res);
}'

我需要替换 和 之间的数字,以便它们按升序排列。 像这样的东西:case:

 str <- 'bool rule_cpp(int n, NumericVector x) {
      bool res = false;
      switch(n) {
        case 1: res = x[0] < x[4];  break;
        case 2: res = x[1] >= x[0]; break;
        case 3: res = x[3] == x[4]; break;
        case 4: res = x[0] != x[4]; break;
        case 5: res = x[1] >= x[0]; break;
        case 6: res = x[3] <= x[4]; break;
        case 7: res = x[0] < x[4];  break;
        case 8: res = x[1] >= x[0]; break;
        case 9: res = x[0] != x[4]; break;
        case 10: res = x[1] >= x[0]; break;
        case 11: res = x[3] <= x[4]; break;
        case 12: res = x[0] < x[4];  break;
        case 13: res = x[1] >= x[0]; break;
          default: stop("Invalid rule number");
      }
      return(res);
    }'

我试图解决这个问题

matches <- stringr::str_match_all(str, "case (\\d+):")[[1]][,2]
n_cases <- seq_along(matches)
new_cases <- paste("case", n_cases, ":")
new_str <- gsub(pattern = "case (\\d+):", new_cases, str)

但我做不到,总的来说,我怀疑我的想法是错误的

r 正则表达式 字符串

评论

2赞 IRTFM 10/12/2023
我怀疑你需要这个包。也许@GGrothendieck(那个包非常有创造力的作者)会出现并帮助我们俩。gsubfn
0赞 r2evans 10/12/2023
(我很期待GG的替代方法:-)

答:

4赞 r2evans 10/12/2023 #1

以下是使用 / 的一种方法:gregexprregmatches

gre <- gregexpr("case [0-9]+:", str)
regmatches(str, gre) <- lapply(gre, function(z) sprintf("case %s:", seq_along(z)))
cat(str, "\n")
# bool rule_cpp(int n, NumericVector x) {
#   bool res = false;
#   switch(n) {
#     case 1: res = x[0] < x[4];  break;
#     case 2: res = x[1] >= x[0]; break;
#     case 3: res = x[3] == x[4]; break;
#     case 4: res = x[0] != x[4]; break;
#     case 5: res = x[1] >= x[0]; break;
#     case 6: res = x[3] <= x[4]; break;
#     case 7: res = x[0] < x[4];  break;
#     case 8: res = x[1] >= x[0]; break;
#     case 9: res = x[0] != x[4]; break;
#     case 10: res = x[1] >= x[0]; break;
#     case 11: res = x[3] <= x[4]; break;
#     case 12: res = x[0] < x[4];  break;
#     case 13: res = x[1] >= x[0]; break;
#       default: stop("Invalid rule number");
#   }
#   return(res);
# } 
1赞 joshbrows 10/12/2023 #2

这是另一种方法。

  library(tidyverse)
  
  pattern <- r'(case \d+)'
  count_cases <- str_count(str, pattern = pattern)
  replacements <- seq(1, count_cases)
  
  str_ordered <-
    str %>% 
    str_replace_all(
      pattern = pattern,
      r'(case replace_me)'
    )
  
  for(replacement in replacements){
    str_ordered <- 
      str_ordered %>% 
      str_replace(
        pattern = r'(replace_me)',
        as.character(replacement)
      )
  }
  
  str_ordered %>% 
    cat
#> bool rule_cpp(int n, NumericVector x) {
#>   bool res = false;
#>   switch(n) {
#>     case 1: res = x[0] < x[4];  break;
#>     case 2: res = x[1] >= x[0]; break;
#>     case 3: res = x[3] == x[4]; break;
#>     case 4: res = x[0] != x[4]; break;
#>     case 5: res = x[1] >= x[0]; break;
#>     case 6: res = x[3] <= x[4]; break;
#>     case 7: res = x[0] < x[4];  break;
#>     case 8: res = x[1] >= x[0]; break;
#>     case 9: res = x[0] != x[4]; break;
#>     case 10: res = x[1] >= x[0]; break;
#>     case 11: res = x[3] <= x[4]; break;
#>     case 12: res = x[0] < x[4];  break;
#>     case 13: res = x[1] >= x[0]; break;
#>       default: stop("Invalid rule number");
#>   }
#>   return(res);
#> }

创建于 2023-10-11 使用 reprex v2.0.2

评论

2赞 joshbrows 10/12/2023
@r2evans,好点子。固定。