Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 删除连续运行的字符中的重复项_R_Regex_Indexing - Fatal编程技术网

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="" )