假设这样的字符串向量:
x <- c("abc", "abcde", "abcde123")
我想在给定字符串的每个元素之间添加分隔符(逗号或其他东西),以实现类似这样的功能(此处的分隔符是逗号):
[1] "a,b,c" "a,b,c,d,e" "a,b,c,d,e,1,2,3"
我能够做到:
sapply(strsplit(x, "", fixed = TRUE), function(x) paste(x, collapse = ","))
但是,我很好奇是否有其他方法可以实现它。
答案 0 :(得分:6)
1)使用零宽度匹配。两个(...)分别在我们想要逗号之前和之后匹配一个字符,但由于它们不占用任何字符,因此它们为零宽度。
>gsub("(?<=.)(?=.)", ",", x, perl = TRUE)
## [1] "a,b,c" "a,b,c,d,e" "a,b,c,d,e,1,2,3"
1a)。在这里,我们将一个字符和一个非消耗性后跟字符匹配,然后将其替换为匹配的字符和逗号。
gsub("(.)(?=.)", "\\1,", x, perl = TRUE)
## [1] "a,b,c" "a,b,c,d,e" "a,b,c,d,e,1,2,3"
2)插入和修剪另一种方法是用逗号替换边界,然后在开头和结尾处修剪逗号。这不需要perl正则表达式。确保不要与此一起使用perl = TRUE。它对\ b的处理方式有所不同。
gsub("^,|,$", "", gsub("\\b", ",", x))
## [1] "a,b,c" "a,b,c,d,e" "a,b,c,d,e,1,2,3"
\\K
也可以使用\\b
代替perl = TRUE
。
2a)在R 3.6(但不更早)中,trimws
具有允许修剪任意字符的参数,因此可以简化为:
trimws(gsub("\\b", ",", x), whitespace = ",")
## [1] "a,b,c" "a,b,c,d,e" "a,b,c,d,e,1,2,3"
2b)此变体甚至可以在3.6之前的版本中使用,但假定字符串中没有制表符。它用制表符替换每个边界,修剪掉两端的空白,然后用逗号替换制表符。
chartr("\t", ",", trimws(gsub("\\b", "\t", x)))
## [1] "a,b,c" "a,b,c,d,e" "a,b,c,d,e,1,2,3"
2c)从这个问题下的讨论看来,逗号只是一个示例,就发布者而言,空格也一样好。在这种情况下,我们可以将其简化为:
trimws(gsub("\\b", " ", x))
## [1] "a b c" "a b c d e" "a b c d e 1 2 3"
3)\ B 用逗号替换非边界。确保指定perl正则表达式。如果字符串包含字母数字,但如果包含非单词字符,则不可以。
gsub("\\B", ",", x, perl = TRUE)
## [1] "a,b,c" "a,b,c,d,e" "a,b,c,d,e,1,2,3"
答案 1 :(得分:0)
这是怎么了?您可以利用paste
是矢量化这一事实,而跳过funcion
的实现。
sapply(strsplit(x, ""), paste, collapse=",")
# [1] "a,b,c" "a,b,c,d,e" "a,b,c,d,e,1,2,3"
或者,您可以使用gregexpr
(受@Rich Scriven的启发)。
sapply(regmatches(x, gregexpr(".", x)), paste, collapse=",")
# [1] "a,b,c" "a,b,c,d,e" "a,b,c,d,e,1,2,3"