有人知道如何在表达式中找到字符串的第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-1patvalue替换为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"


(我们可以使用subsub.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参数。

07-24 09:51
查看更多