String 在字符串中的特定位置插入字符

String 在字符串中的特定位置插入字符,string,r,String,R,我想在字符串中的特定位置插入一个额外字符(或一个新字符串)。例如,我想在abcefg中的第四个位置插入d,以获得abcdefg 现在我正在使用: old <- "abcefg" n <- 4 paste(substr(old, 1, n-1), "d", substr(old, n, nchar(old)), sep = "") old您可以使用正则表达式和gsub实现这一点 gsub('^([a-z]{3})([a-z]+)$', '\\1d\\2', old) # [1] "a

我想在字符串中的特定位置插入一个额外字符(或一个新字符串)。例如,我想在
abcefg
中的第四个位置插入
d
,以获得
abcdefg

现在我正在使用:

old <- "abcefg"
n <- 4
paste(substr(old, 1, n-1), "d", substr(old, n, nchar(old)), sep = "")

old您可以使用正则表达式和
gsub
实现这一点

gsub('^([a-z]{3})([a-z]+)$', '\\1d\\2', old)
# [1] "abcdefg"
如果要动态执行此操作,可以使用
paste
创建表达式:

letter <- 'd'
lhs <- paste0('^([a-z]{', n-1, '})([a-z]+)$')
rhs <- paste0('\\1', letter, '\\2')
gsub(lhs, rhs, old)
# [1] "abcdefg"
这样,任何三个字符都将匹配,而不仅仅是小写。DWin还建议使用
sub
而不是
gsub
。这样,您就不必太担心
^
了,因为
sub
将只匹配第一个实例。但我喜欢在正则表达式中显式表达,只在我理解它们并发现需要更多的通用性时才转向更一般的正则表达式


正如Greg Snow所指出的,您可以使用另一种形式的正则表达式来查找匹配项:

sub( '(?<=.{3})', 'd', old, perl=TRUE )
或者对于他的
sub
正则表达式:

lhs <- sprintf('(?<=.{%d})',n-1)

lhs@Justin的答案是我实际处理这个问题的方式,因为它的灵活性,但也可能是一个有趣的方法

您可以将字符串视为“固定宽度格式”,并指定要插入字符的位置:

paste(read.fwf(textConnection(old), 
               c(4, nchar(old)), as.is = TRUE), 
      collapse = "d")
使用
sapply
时的输出特别好,因为您可以将原始字符串视为“名称”


newold您最初的操作方法(即在索引处拆分字符串并粘贴到插入的文本中)可以制作成一个通用函数,如下所示:

split_str_by_index <- function(target, index) {
  index <- sort(index)
  substr(rep(target, length(index) + 1),
         start = c(1, index),
         stop = c(index -1, nchar(target)))
}

#Taken from https://stat.ethz.ch/pipermail/r-help/2006-March/101023.html
interleave <- function(v1,v2)
{
  ord1 <- 2*(1:length(v1))-1
  ord2 <- 2*(1:length(v2))
  c(v1,v2)[order(c(ord1,ord2))]
}

insert_str <- function(target, insert, index) {
  insert <- insert[order(index)]
  index <- sort(index)
  paste(interleave(split_str_by_index(target, index), insert), collapse="")
}
这允许您在索引向量给定的位置插入字符向量。
split\u str\u by_index
interleave
函数本身也很有用

编辑:


我修改了代码,以允许以任何顺序进行索引。在此之前,索引需要按升序排列。

stringi
再次打包救援!最简单、最优雅的解决方案

stri_sub
函数允许您提取字符串的部分内容,并将其替换为以下内容:

x <- "abcde"
stri_sub(x, 1, 3) # from first to third character
# [1] "abc"
stri_sub(x, 1, 3) <- 1 # substitute from first to third character
x
# [1] "1de"

x我制作了一个名为
substr1
的自定义函数,用于在字符串中提取、替换和插入字符。在每次会话开始时运行这些代码。请随意试用,如果需要改进,请告诉我

# extraction
substr1 <- function(x,y) {
  z <- sapply(strsplit(as.character(x),''),function(w) paste(na.omit(w[y]),collapse=''))
  dim(z) <- dim(x)
  return(z) }

# substitution + insertion
`substr1<-` <- function(x,y,value) {
  names(y) <- c(value,rep('',length(y)-length(value)))
  z <- sapply(strsplit(as.character(x),''),function(w) {
    v <- seq(w)
    names(v) <- w
    paste(names(sort(c(y,v[setdiff(v,y)]))),collapse='') })
  dim(z) <- dim(x)
  return(z) }

# demonstration
abc <- 'abc'
substr1(abc,1)
# "a"
substr1(abc,c(1,3))
# "ac"
substr1(abc,-1)
# "bc"
substr1(abc,1) <- 'A'
# "Abc"
substr1(abc,1.5) <- 'A'
# "aAbc"
substr1(abc,c(0.5,2,3)) <- c('A','B')
# "AaB"
#提取

substr1我花了一些时间理解正则表达式,后来我用我的数字找到了方法

最终的结果是

old <- "89580000"
gsub('^([0-9]{5})([0-9]+)$', '\\1-\\2', old)

old我喜欢正则表达式解决方案,但会使用
sub()
,我建议使用更通用的模式:
^(.{3})(.*$)“
。目前,任何非小写字母都会破坏替换。我喜欢尽可能具体地使用正则表达式,以便它们失败而不是意外成功。但你说得很对@Justin感谢您指出
gsub
函数。我知道这些模式匹配功能非常强大,但实际上不知道如何使用它们。它们看起来很复杂。我需要用谷歌搜索更多关于它们的信息。你可以使用查找匹配来获得正确的位置,而无需捕获:
sub('(?另外,我认为在动态情况下,
sprintf
可能比
paste0
更简单的情况下:
lhs您知道如何使用这种优雅的方法在多个位置插入吗?在这里,我天真地尝试使用
reduce()
但它看起来很笨拙:解决一个困扰了我一段时间的问题的极好方法有趣的函数但是
stri\u sub Good point@Bastien-你可以创建一个问题,也许我们应该添加另一个函数-
stri\u sub\u pipe
来解决这个问题?
> insert_str("1234567890", c("a", "b", "c"), c(5, 9, 3))
[1] "12c34a5678b90"
x <- "abcde"
stri_sub(x, 1, 3) # from first to third character
# [1] "abc"
stri_sub(x, 1, 3) <- 1 # substitute from first to third character
x
# [1] "1de"
x <- "abcde"
stri_sub(x, 3, 2) # from 3 to 2 so... zero ?
# [1] ""
stri_sub(x, 3, 2) <- 1 # substitute from 3 to 2 ... hmm
x
# [1] "ab1cde"
# extraction
substr1 <- function(x,y) {
  z <- sapply(strsplit(as.character(x),''),function(w) paste(na.omit(w[y]),collapse=''))
  dim(z) <- dim(x)
  return(z) }

# substitution + insertion
`substr1<-` <- function(x,y,value) {
  names(y) <- c(value,rep('',length(y)-length(value)))
  z <- sapply(strsplit(as.character(x),''),function(w) {
    v <- seq(w)
    names(v) <- w
    paste(names(sort(c(y,v[setdiff(v,y)]))),collapse='') })
  dim(z) <- dim(x)
  return(z) }

# demonstration
abc <- 'abc'
substr1(abc,1)
# "a"
substr1(abc,c(1,3))
# "ac"
substr1(abc,-1)
# "bc"
substr1(abc,1) <- 'A'
# "Abc"
substr1(abc,1.5) <- 'A'
# "aAbc"
substr1(abc,c(0.5,2,3)) <- c('A','B')
# "AaB"
old <- "89580000"
gsub('^([0-9]{5})([0-9]+)$', '\\1-\\2', old)