有人知道如何在表达式中找到字符串的第n次出现以及如何用正则表达式替换它吗?
例如我有以下字符串
txt <- "aaa-aaa-aaa-aaa-aaa-aaa-aaa-aaa-aaa-aaa"
我想用“ |”代替“-”的第五次出现
和“ ||”在“-”的第七次出现喜欢
[1] aaa-aaa-aaa-aaa-aaa|aaa-aaa||aaa-aaa-aaa
我该怎么做呢?
谢谢,
弗洛里安
最佳答案
(1)sub可以使用sub
在单个正则表达式中完成:
> sub("(^(.*?-){4}.*?)-(.*?-.*?)-", "\\1|\\3||", txt, perl = TRUE)
[1] "aaa-aaa-aaa-aaa-aaa|aaa-aaa||aaa-aaa-aaa"
(2)两次,或两次调用
sub
的此变体:> txt2 <- sub("(^(.*?-){6}.*?)-", "\\1|", txt, perl = TRUE)
> sub("(^(.*?-){4}.*?)-", "\\1||", txt2, perl = TRUE)
[1] "aaa-aaa-aaa-aaa-aaa|aaa-aaa||aaa-aaa-aaa"
(3)sub.fun或此变体创建函数
sub.fun
进行替代。它利用gsubfn package中的fn$
将n-1
,pat
和value
替换为sub
参数。首先定义指示的函数,然后调用两次。library(gsubfn)
sub.fun <- function(x, pat, n, value) {
fn$sub( "(^(.*?-){`n-1`}.*?)$pat", "\\1$value", x, perl = TRUE)
}
> sub.fun(sub.fun(txt, "-", 7, "||"), "-", 5, "|")
[1] "aaa-aaa-aaa-aaa-aaa|aaa-aaa||aaa-aaa-aaa"
(我们可以使用
sub
或sub.fun
修改paste
主体中sprintf
的参数以提供基本的R解决方案,但要付出一些额外的冗长性。)可以将其重新构造为替换函数,并给出以下令人愉快的顺序:
"sub.fun<-" <- sub.fun
tt <- txt # make a copy so that we preserve the input txt
sub.fun(tt, "-", 7) <- "||"
sub.fun(tt, "-", 5) <- "|"
> tt
[1] "aaa-aaa-aaa-aaa-aaa|aaa-aaa||aaa-aaa-aaa"
(4)gsubfn使用gsubfn package中的
gsubfn
我们可以使用一个特别简单的正则表达式(它只是"-"
),并且代码具有相当简单的结构。我们通过原型方法执行替换。包含该方法的原型对象将代替替换字符串。这种方法的简单性导致了gsubfn
自动使count
变量可用于以下方法的事实:library(gsubfn) # gsubfn also pulls in proto
p <- proto(fun = function(this, x) {
if (count == 5) return("|")
if (count == 7) return("||")
x
})
> gsubfn("-", p, txt)
[1] "aaa-aaa-aaa-aaa-aaa|aaa-aaa||aaa-aaa-aaa"
更新:一些更正。
更新2:在(3)中添加了替换函数方法。
更新3:在
pat
中添加了sub.fun
参数。