删除字符串 R 中的连续重复项

removing consecutive duplicates in strings R

我想折叠两个字符串 s1 = "word1 word2 word3"s2 = "word2 word3 word4" 但删除额外的(未来)连续 overlap/duplicate ("word2 word3")。也就是说,我应该获得 s = "word1 word2 word3 word4" 而不是 s = "word1 word2 word3 word2 word3 word4"

更简单地说,它应该也适用于单个单词重叠:s1 = "word1 word2"s2 = "word2 word3" 应该给我 s = word1 word2 word3" 而不是 s = "word1 word2 word2 word3"

我使用 wordnumber 用于说明目的,但当然它应该适用于任何单词...

对结果使用 unique,应该会删除所有重复项。
也许还可以使用 sort?


编辑:抱歉,我的第一个回答完全没有抓住要点。这是基于 stringr-package 的修订解决方案,我认为应该可行。这个想法是首先将字符串拆分为向量,然后比较向量并检查是否存在重叠 - 最后根据是否检测到重叠来连接向量。

s1 = "word1 word2  word3"
s2 = "word2 word3 word4"

library(stringr)
.s1_splitted <- str_split(
    string = s1,
    pattern = "\ +")[[1]]
.s2_splitted <- str_split(
    string = s2,
    pattern = "\ +")[[1]]


.matches12 <- charmatch(
    x = .s1_splitted,
    table = .s2_splitted)

如果最后一个数字不同于NA,并且比 .s1_splitted的长度,然后检查向量的末尾 看起来应该这样做。

.last_element <- tail(.matches12, n = 1)
if (! is.na(.last_element)) {
    if (.last_element <= length(.s1_splitted)) {
        .overlap <- identical(
            x = 1:.last_element,
            y = tail(x = .matches12,
                     n = .last_element))
    }
} else
    .overlap <- FALSE

根据重叠加入组件。

if (.overlap) {
    .joined <- c(
        head(x = .s1_splitted,
             n = - .last_element),
        .s2_splitted)
} else
    .joined <- c(.s1_splitted,
                  .s2_splitted)

转换回字符串

.result <- paste(.joined, collapse = " ")

这出乎意料地困难,但我相信我有解决办法:

sjoin <- function(s1,s2) {
    ss1 <- strsplit(s1,'\s+')[[1L]];
    ss2 <- strsplit(s2,'\s+')[[1L]];
    if (length(ss1)==0L) return(s2);
    if (length(ss2)==0L) return(s1);
    n <- 0L; for (i in seq(min(length(ss1),length(ss2)),1L))
        if (all(ss1[seq(to=length(ss1),len=i)]==ss2[seq(1L,len=i)])) {
            n <- i;
            break;
        }; ## end if
    paste(collapse=' ',c(ss1,if (n==0L) ss2 else ss2[-1:-n]));
}; ## end sjoin()
sjoin('1 2 3','2 3 4');
## [1] "1 2 3 4"
sjoin('1 2 3 x','2 3 4');
## [1] "1 2 3 x 2 3 4"
sjoin('1 2 3','x 2 3 4');
## [1] "1 2 3 x 2 3 4"
sjoin('','')
## [1] ""
sjoin('a','');
## [1] "a"
sjoin('','a');
## [1] "a"
sjoin('a','a')
## [1] "a"
sjoin('a b c','a b c');
## [1] "a b c"
sjoin('a b c','c');
## [1] "a b c"
sjoin('a b c','c d');
## [1] "a b c d"
sjoin('b','b c d');
## [1] "b c d"
sjoin('a b','b c d');
## [1] "a b c d"