R 正则表达式:替换第n次出现

R 正则表达式:替换第n次出现,r,R,有人知道如何在表达式中找到字符串的第n次出现,以及如何用正则表达式替换它吗 例如,我有以下字符串 txt <- "aaa-aaa-aaa-aaa-aaa-aaa-aaa-aaa-aaa-aaa" 我该怎么做 谢谢, Florian一种方法是使用gregexpr查找-的位置: posns <- gregexpr("-",txt)[[1]] 另一种可能性是使用Hadley的stringr包,它为我编写的函数奠定了基础: require(stringr) replace.nth &l

有人知道如何在表达式中找到字符串的第n次出现,以及如何用正则表达式替换它吗

例如,我有以下字符串

txt <- "aaa-aaa-aaa-aaa-aaa-aaa-aaa-aaa-aaa-aaa"
我该怎么做

谢谢,
Florian

一种方法是使用
gregexpr
查找
-
的位置:

posns <- gregexpr("-",txt)[[1]]

另一种可能性是使用Hadley的
stringr
包,它为我编写的函数奠定了基础:

require(stringr)

replace.nth <- function(string, pattern, replacement, n) {
    locations <- str_locate_all(string, pattern)
    str_sub(string, locations[[1]][n, 1], locations[[1]][n, 2]) <- replacement
    string
}

txt <- "aaa-aaa-aaa-aaa-aaa-aaa-aaa-aaa-aaa-aaa"

txt.new <- replace.nth(txt, "-", "|", 5)
txt.new <- replace.nth(txt.new, "-", "||", 7)
txt.new
# [1] "aaa-aaa-aaa-aaa-aaa|aaa-aaa-aaa||aaa-aaa"
require(stringr)
replace.nth(1)sub可以用
sub
在单个正则表达式中完成:

> sub("(^(.*?-){4}.*?)-(.*?-.*?)-", "\\1|\\3||", txt, perl = TRUE)
[1] "aaa-aaa-aaa-aaa-aaa|aaa-aaa||aaa-aaa-aaa"
(2)sub两次或调用
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"
(我们本可以使用
paste
sprintf
sub.fun
正文中的参数修改为
sub
,以给出基本的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"
更新:一些更正

更新2:在(3)中添加了替换功能方法


更新3:将
pat
参数添加到
sub.fun

谢谢!这就是我要找的for@Henrik,我认为你的解决方案有一点错误。正如您从输出中看到的,原始系列的第8个“-”已更改,而不是预期的第7个。您必须更改这两行,以便从将第7个“-”更改为“| |”的行开始,否则其中一个“-”已更改。:-)太好了,很有可能!谢谢,弗洛里安
> txt2 <- sub("(^(.*?-){6}.*?)-", "\\1|", txt, perl = TRUE)
> sub("(^(.*?-){4}.*?)-", "\\1||", txt2, perl = TRUE)
[1] "aaa-aaa-aaa-aaa-aaa|aaa-aaa||aaa-aaa-aaa"
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.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"
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"