我有
x<-c('abczzzdef','abcxxdef')
我想要一个功能
fn(x)
返回长度为2的向量
[1] 'zzz' 'xx'
如何?
(我已尝试搜索答案,但搜索条件如“部分匹配&#39;给我一些完全不同的内容”
更新
&#39;长度为2的向量&#39;表示length(fn(x))
为2
,fn(x)[1]
表示"zzz"
,fn(x)[2]
表示"xx"
。
在尝试了所提供的答案后,我意识到我还不够具体。
x<-c('zzzabcdef','xxabcdef')
或者它可能在最后。但是2个字符串总是在相同的位置(即在开头,或者在中间,或者在结尾都是)。zzz
和xx
显然是通用名称。它们可以是不同的东西(数字,字母,符号)和不同的长度(不一定是3和2)。abc
和def
。我有一些测试用例
x1<-c('abcxxxttt','abczzttt')
x2<-c('abcxxxdef','abczz126gsdef')
x3<-c('xx_x123../t','z_z126gs123../t')
fn(x1)
应该"xxx" "zz"
fn(x2)
应该"xxx" "zz126gs"
fn(x3)
应该"xx_x" "z_z126gs"
答案 0 :(得分:1)
x<-c('abczzzdef','abcxxdef')
fn <- function(x) unlist(regmatches(x, gregexpr("(.)\\1+", x)))
fn(x)
# [1] "zzz" "xx"
答案 1 :(得分:1)
首先,在问题的第一个版本中包含所有细节会更好。没有必要浪费时间,因为你没有清楚地解释你需要什么,所以不得不花时间提出不适合你的解决方案。如果您在问题得到解答之后需要更改一个问题,那么最好提出一个新问题,而不是完全改变第一个问题。
你要做的事情,找到字符串中最大的非共享部分,对于计算机来说可能是一个非常混乱的过程。字符串不相似性的某种标准度量是R在adist
函数中实现的广义Levenshtein距离。它可以生成一个字符串,告诉您如何通过匹配,插入,删除和替换将一个字符串转换为另一个字符串。如果我找到最长的匹配字符串,我会非常清楚在哪里提取唯一信息。
因此,该方法主要侧重于提取最佳匹配之外的区域。这是匹配
的功能fn <- function(x) {
ld <- attr(adist(x[1], x[2], counts=T,
costs=c(substitutions=500)),"trafos")[1,1]
starts <- gregexpr("M+", ld)[[1]]
lens <- attr(starts,"match.length")
starts <- as.vector(starts)
ends <- starts + lens - 1
bm <- which.max(lens)
if (starts[bm]==1 | ends[bm]==nchar(ld)) {
#beg/end
for( i in which(starts==1 | ends==nchar(ld))) {
substr(ld, starts[i], ends[i]) <-
paste(rep("X", lens[i]), collapse="")
}
} else {
#middle
substr(ld, starts[bm], ends[bm]) <-
paste(rep("X", lens[bm]), collapse="")
}
tr <- strsplit(ld,"")[[1]]
x1 <- cumsum(tr %in% c("D","M","X"))[!tr %in% c("X","I")]
x2 <- cumsum(tr %in% c("I","M","X"))[!tr %in% c("X","D")]
c(substr(x[1], min(x1), max(x1)), substr(x[2], min(x2), max(x2)))
}
现在我们可以将它应用于您的测试数据
x1 <- c('abcxxxttt','abczzttt')
x2 <- c('abcxxxdef','abczz126gsdef')
x3 <- c('xx_x123../t','z_z126gs123../t')
fn(x1)
# [1] "xxx" "zz"
fn(x2)
# [1] "xxx" "zz126gs"
fn(x3)
# [1] "xx_x" "z_z126gs"
所以我们得到你期望的结果。在这里,我做了一些错误检查。我假设总会有一些重叠和一些不重叠的区域。如果不成立,则该功能可能会产生错误或意外结果。
答案 2 :(得分:0)
gsub("([^xz]*)([xz]*)([^xz]*)", "\\2", x)
[1] "zzz" "xx"
> getxz <- function(x, str) gsub(paste0("([^",str, ']*)([', str, ']*)([^', str, ']*)'),
"\\2", x)
> getxz(x=x,"xz")
[1] "zzz" "xx"
为了回应新的例子,我提供了这些测试,我认为这些测试有三个成功:
> getxz(x=x1,"xz_")
[1] "xxx" "zz"
> getxz(x=x2,"xz_")
[1] "xxx" "zz"
> getxz(x=x3,"xz_")
[1] "xx_x" "z_z"