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

Pat*_* Li 50 string r

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

现在我正在使用:

old <- "abcefg"
n <- 4
paste(substr(old, 1, n-1), "d", substr(old, n, nchar(old)), sep = "")
Run Code Online (Sandbox Code Playgroud)

我可以为这个任务编写一个单行的简单函数,但我很好奇是否有一个现有的函数.

Jus*_*tin 58

您可以使用正则表达式和gsub.

gsub('^([a-z]{3})([a-z]+)$', '\\1d\\2', old)
# [1] "abcdefg"
Run Code Online (Sandbox Code Playgroud)

如果要动态执行此操作,可以使用paste以下命令创建表达式:

letter <- 'd'
lhs <- paste0('^([a-z]{', n-1, '})([a-z]+)$')
rhs <- paste0('\\1', letter, '\\2')
gsub(lhs, rhs, old)
# [1] "abcdefg"
Run Code Online (Sandbox Code Playgroud)

根据DWin的评论,您可能希望这更加通用.

gsub('^(.{3})(.*)$', '\\1d\\2', old)
Run Code Online (Sandbox Code Playgroud)

这样任何三个字符都匹配而不仅仅是小写.DWin还建议使用sub而不是gsub.这样您就不必担心这一点^,因为sub只会匹配第一个实例.但是我喜欢在正则表达式中明确表达,而只是在我理解它们时转向更一般的表达式,并且需要更多的通用性.


正如Greg Snow所说,你可以使用另一种形式的正则表达式来查看匹配:

sub( '(?<=.{3})', 'd', old, perl=TRUE )
Run Code Online (Sandbox Code Playgroud)

并且还可以gsub使用sprintf而不是paste0:

lhs <- sprintf('^([a-z]{%d})([a-z]+)$', n-1) 
Run Code Online (Sandbox Code Playgroud)

或者他的sub正则表达式:

lhs <- sprintf('(?<=.{%d})',n-1)
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢正则表达式解决方案,但会使用`sub()`,我建议使用更通用的模式:`^(.{3})(.*$)"`。目前任何非小写字母都会破坏替换. (2认同)

bar*_*nus 17

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"
Run Code Online (Sandbox Code Playgroud)

但是如果你这样做:

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"
Run Code Online (Sandbox Code Playgroud)

然后没有删除任何字符但插入新的字符.那不是很酷吗?:)

  • @Bastien &amp; @ bartektartanus 你可能知道这一点:现在可以通过``stringi::stri_sub_replace(x, 3,2, value = 1)``进行管道传输 (7认同)
  • 解决一段困扰我的问题的优秀方法 (4认同)
  • 您知道如何使用这种优雅的方法在多个位置插入吗? (2认同)
  • 有趣的函数,但是 `stri_sub &lt;-` 不容易放入管道中,而 `sub` 函数却可以。(只有当你想通过管道传输时这才重要......) (2认同)

A5C*_*2T1 8

@贾斯汀的答案是其实我的方法,因为它的灵活性这个问题的方法,但是也可能是一个有趣的方法.

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

paste(read.fwf(textConnection(old), 
               c(4, nchar(old)), as.is = TRUE), 
      collapse = "d")
Run Code Online (Sandbox Code Playgroud)

特别好的是使用时的输出sapply,因为你可以看到原始字符串作为"名称".

newold <- c("some", "random", "words", "strung", "together")
sapply(newold, function(x) paste(read.fwf(textConnection(x), 
                                          c(4, nchar(x)), as.is = TRUE), 
                                 collapse = "-WEE-"))
#            some          random           words          strung        together 
#   "some-WEE-NA"   "rand-WEE-om"    "word-WEE-s"   "stru-WEE-ng" "toge-WEE-ther" 
Run Code Online (Sandbox Code Playgroud)