string 在字符串的特定位置插入一个字符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13863599/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Insert a character at a specific location in a string
提问by Patrick Li
I would like to insert an extra character (or a new string) at a specific location in a string. For example, I want to insert d
at the fourth location in abcefg
to get abcdefg
.
我想在字符串的特定位置插入一个额外的字符(或一个新字符串)。例如,我想d
在第四个位置插入abcefg
以获取abcdefg
.
Now I am using:
现在我正在使用:
old <- "abcefg"
n <- 4
paste(substr(old, 1, n-1), "d", substr(old, n, nchar(old)), sep = "")
I could write a one-line simple function for this task, but I am just curious if there is an existing function for that.
我可以为此任务编写一个简单的单行函数,但我很好奇是否有一个现有的函数。
回答by Justin
You can do this with regular expressions and gsub
.
您可以使用正则表达式和gsub
.
gsub('^([a-z]{3})([a-z]+)$', '\1d\2', old)
# [1] "abcdefg"
If you want to do this dynamically, you can create the expressions using paste
:
如果要动态执行此操作,可以使用paste
以下方法创建表达式:
letter <- 'd'
lhs <- paste0('^([a-z]{', n-1, '})([a-z]+)$')
rhs <- paste0('\1', letter, '\2')
gsub(lhs, rhs, old)
# [1] "abcdefg"
as per DWin's comment,you may want this to be more general.
根据 DWin 的评论,您可能希望这更通用。
gsub('^(.{3})(.*)$', '\1d\2', old)
This way any three characters will match rather than only lower case. DWin also suggests using sub
instead of gsub
. This way you don't have to worry about the ^
as much since sub
will only match the first instance. But I like to be explicit in regular expressions and only move to more general ones as I understand them and find a need for more generality.
这样,任何三个字符都将匹配,而不仅仅是小写。DWin 还建议使用sub
代替gsub
. 这样你就不必担心^
那么多,因为sub
只会匹配第一个实例。但是我喜欢在正则表达式中明确表达,并且只在我理解它们并发现需要更多通用性时才转向更通用的表达式。
as Greg Snow noted, you can use another form of regular expression that looks behind matches:
正如 Greg Snow 所指出的,您可以使用另一种形式的正则表达式来查看匹配项:
sub( '(?<=.{3})', 'd', old, perl=TRUE )
and could also build my dynamic gsub
above using sprintf
rather than paste0
:
并且还可以gsub
使用sprintf
而不是在上面构建我的动态paste0
:
lhs <- sprintf('^([a-z]{%d})([a-z]+)$', n-1)
or for his sub
regular expression:
或者他的sub
正则表达式:
lhs <- sprintf('(?<=.{%d})',n-1)
回答by bartektartanus
stringi
package for the rescue once again! The most simple and elegant solution among presented ones.
stringi
再次为救援包!提出的解决方案中最简单和优雅的解决方案。
stri_sub
function allows you to extract parts of the string and substitute parts of it like this:
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"
But if you do this:
但如果你这样做:
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"
then no characters are removed but new one are inserted. Isn't that cool? :)
然后不会删除任何字符,但会插入新的字符。这不是很酷吗?:)
回答by A5C1D2H2I1M1N2O1R2T1
@Justin's answer is the way I'd actually approach this because of its flexibility, but thiscould also be a fun approach.
@贾斯汀的回答是这样的我其实这种做法,因为它的灵活性,但这个也可能是一个有趣的方法。
You can treat the string as "fixed width format" and specify where you want to insert your character:
您可以将字符串视为“固定宽度格式”并指定要插入字符的位置:
paste(read.fwf(textConnection(old),
c(4, nchar(old)), as.is = TRUE),
collapse = "d")
Particularly nice is the output when using sapply
, since you get to see the original string as the "name".
使用时的输出特别好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"
回答by Zach Foster
Your original way of doing this (i.e. splitting the string at an index and pasting in the inserted text) could be made into a generic function like so:
您这样做的原始方法(即在索引处拆分字符串并粘贴插入的文本)可以变成一个通用函数,如下所示:
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="")
}
Example usage:
用法示例:
> insert_str("1234567890", c("a", "b", "c"), c(5, 9, 3))
[1] "12c34a5678b90"
This allows you to insert a vector of characters at the locations given by a vector of indexes. The split_str_by_index
and interleave
functions are also useful on their own.
这允许您在索引向量给定的位置插入字符向量。该split_str_by_index
和interleave
功能也对自己有用。
Edit:
编辑:
I revised the code to allow for indexes in any order. Before, indexes needed to be in ascending order.
我修改了代码以允许以任何顺序进行索引。以前,索引需要按升序排列。
回答by Joni Hoppen
It took me some time to understand the regular expression, afterwards I found my way with the numbers I had
我花了一些时间来理解正则表达式,后来我找到了我的数字
The end result was
最终结果是
old <- "89580000"
gsub('^([0-9]{5})([0-9]+)$', '\1-\2', old)
回答by dasf
I've made a custom function called substr1
to deal with extracting, replacing and inserting chars in a string. Run these codes at the start of every session. Feel free to try it out and let me know if it needs to be improved.
我创建了一个自定义函数,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"