R 删除连续运行的字符中的重复项
我的字符串包含大量重复项,如下所示:R 删除连续运行的字符中的重复项,r,regex,indexing,R,Regex,Indexing,我的字符串包含大量重复项,如下所示: tst <- c("C>C>C>B>B>B>B>C>C>*>*>*>*>*>C", "A>A>A", "*>B>B", "A>A>A>A>A>*>A>A>A>*>*>*>*>A>A&
tst <- c("C>C>C>B>B>B>B>C>C>*>*>*>*>*>C", "A>A>A", "*>B>B",
"A>A>A>A>A>*>A>A>A>*>*>*>*>A>A", "*>C>C", "A")
我成功提取了重复的大写字母:
library(stringr)
unlist(str_extract_all(gsub(">", "", tst), "(.)(?=\\1)"))
[1] "C" "C" "B" "B" "B" "C" "*" "*" "*" "*"
但我有点被困在这里了。我的直觉是,返回索引的函数可能会有所帮助,但不知道在这种情况下如何实现它
有什么想法吗
编辑:
我自己也离解决方案不远——只是使用消极的前瞻(而不是积极的前瞻)就可以做到:
str_extract_all(gsub(">", "", tst), "(.)(?!\\1)")
[[1]]
[1] "C" "B" "C" "*" "C"
[[2]]
[1] "A"
[[3]]
[1] "*" "B"
[[4]]
[1] "A" "*" "A" "*" "A"
[[5]]
[1] "*" "C"
[[6]]
[1] "A"
我们可以使用gsub
gsub("([A-Z*]>)\\1+", "\\1", tst)
#[1] "C>B>C>*>C"
要获得第二个结果,请删除
gsub(">", "", gsub("([A-Z*]\\>)\\1+", "\\1", tst) ,fixed = TRUE)
#[1] "CBC*C"
根据OP下面的评论,可能是
gsub("(.)\\1+", "\\1", gsub(">", "", tst))
#[1] "CBC*C"
gsub("(.)\\1+", "\\1", gsub(">", "", "A>"))
#[1] "A"
gsub("(.)\\1+", "\\1", gsub(">", "", "A>A"))
#[1] "A"
gsub("(.)\\1+", "\\1", gsub(">", "", "A>A>A>A"))
#[1] "A"
对于对regex过敏的人:
paste(rle(strsplit(tst, ">")[[1]])$values, collapse = ">") # or collapse = ""
[1] "C>B>C>*>C"
…当然,对于包含小写字母的字符串,如“A>A>A>A>A>A”
另一种获取CBC*C
的方法可能是使用2个组,并在替换中使用组2
((.)>)\1+
范例
tst <- "C>C>C>B>B>B>B>C>C>*>*>*>*>*>C"
gsub("((.)>)\\1+", "\\2", tst)
一种有点通用的基本R方法,没有regexp
这里的想法是将字符串分解为多个组,然后依次删除重复模式(这使其不同于unique
):
这是一个很好的解决方案。为什么解决方案在这样的问题上失败:gsub((.)>)\\1+,“\\2”,“a>a>a>a”)
?如何对其进行编辑以使其也适用于此类案例?@ChrisRuehlemann这取决于预期结果。当前模式重复捕获组以获得连续的部分。替换使用内部第二组。@ChrisRuehlemann它与最后一个A不匹配,因为它不在重复模式中。您可以选择匹配第二个组(.)>)\1+\2*
,以匹配相同的尾随字符。谢谢。事实证明,最好的解决方案确实是gsub(()\\1+,“\\1”,gsub(“>,”,tst))
@阿克伦只是在几分钟前发布的。因此,为了公平起见,我不得不接受他的回答。@ChrisRuehlemann对A
的期望是什么,只是这个,没有什么else@ChrisRuehlemann这将返回gsub(“()\\1+”,“\\1”,gsub(“>”,“,“A>A>A>A”))#[1]“A”
在gsub(“()\\1+”,“\\1”,gsub(“>”,“,tst))#[1]“CBC*C”上进行测试
@ChrisRuehlemann这也适用于gsub(()\\1+,“\\1”,gsub(“>,”,“A>A”)#[1]“A”
与gsub(()\\1+\\2*,“\\2”,“A>A”)#[1]“A>A”
tst <- "C>C>C>B>B>B>B>C>C>*>*>*>*>*>C"
gsub("((.)>)\\1+", "\\2", tst)
[1] "CBC*C"
tst <- "C>C>C>B>B>B>B>C>C>*>*>*>*>*>C"
st <- paste(unlist(strsplit(tst,">")),collapse="")
#[1] "CCCBBBBCC*****C"
paste( unlist( sapply( 1:nchar(st), function(x){
if( substr(st,x,x) != substr(st,(x+1),(x+1)) ){ substr(st,x,x) } } ) ), collapse="" )
#[1] "CBC*C"
paste( unlist( sapply( 1:nchar(st), function(x){
a=substr(st,x,x); b=substr(st,(x+1),(x+1));
if( a != b & toupper(a) == a ){ a } else if( toupper(a) != a ){ a } } ) ), collapse="" )