替换R中模板字符串中的字母

Spa*_*man 5 regex string r stringi

给定一个英国邮政编码的"模板",如"A9 9AA",其中"A"是一个字母占位符,"9"是一个数字占位符,我要生成随机字符串邮编像"H8 4GB".字母可以是任何大写字母,编号从0到9.

因此,如果模板是"AA9A 9AA",那么我想要像"WC1A 9LK"这样的字符串.我现在忽略了生成"真实"的邮政编码,所以如果"WC1A"是一个有效的外向代码我就不会感到困扰.

我试图从stringi包中获取函数来解决问题,但问题似乎是替换或匹配模板中的"A"只会替换第一个替换,例如:

 stri_replace_all_fixed("A9 9AA",c("A","A","A"), c("X","Y","Z"), vectorize_all=FALSE)
[1] "X9 9XX"
Run Code Online (Sandbox Code Playgroud)

所以它不会用替换向量中的每个元素替换每个"A"(但这是设计的).

也许stringi我已经错过了某些内容或基础R - 我想将它保存在这些包中,所以我不会膨胀我正在做的事情.

蛮力方法是拆分模板,做替换,将结果粘贴在一起,但我想看看是否有更快,自然的矢量化解决方案.

总结一下:

foo("A9 9AA") # return like "B6 5DE"
foo(c("A9 9AA","A9 9AA","A9A 9AA")) # returns c("Y6 5TH","D4 8JH","W0Z 3KQ")
Run Code Online (Sandbox Code Playgroud)

这是一个非矢量化版本,它依赖于构造表达式并对其进行评估......

random_pc <- function(fmt){
    cc = gsub(" ",'c(" ")',gsub("9","sample(0:9,1)",gsub("A","sample(LETTERS,1)",strsplit(fmt,"")[[1]])))
    paste(eval(parse(text=paste0("c(",paste(cc,collapse=","),")"))),collapse="")    
}

> random_pc("AA9 9AA")
[1] "KO6 1AY"
Run Code Online (Sandbox Code Playgroud)

MKR*_*MKR 4

据我了解,OP想要UK POST CODE以指定的格式随机创建。我认为sprintf可以提供帮助,例如:

sprintf("%s%s %d%d%s", sample(LETTERS,1),sample(LETTERS,1), sample(0:9,1),
                sample(0:9,1), sample(LETTERS,1) )
#1] "BC 59D"
Run Code Online (Sandbox Code Playgroud)

9现在,如果目的是提供使用和 的格式,A那么步骤将是首先9%dA替换%s

选项#2

paste0另一种选择可以通过使用sapply自定义函数来实现:

fmt <- "AA 9AA A"
paste0(sapply(strsplit(fmt,""), getCodeText), collapse = "")
#"YF 7OP Z"


#custom function to generate random characters
getCodeText <- function(x){
  retVal = x
  for(i in seq_along(x)){
    if(x[i] == "A"){
      retVal[i] = sample(LETTERS,1)
    }else if(x[i] == "9"){
      retVal[i] = as.character(sample(0:9,1))
    }
  }
  retVal
}
Run Code Online (Sandbox Code Playgroud)