1) Using zero width matches The two (...) match a character before and after where we want a comma respectively but are zero width in that they do not consume any characters.
gsub("(?<=.)(?=.)", ",", x, perl = TRUE)
## [1] "a,b,c" "a,b,c,d,e" "a,b,c,d,e,1,2,3"
1a) This also works. Here we match a character and a non-consuming following character and replace that with the character matched and a comma.
gsub("(.)(?=.)", "\\1,", x, perl = TRUE)
## [1] "a,b,c" "a,b,c,d,e" "a,b,c,d,e,1,2,3"
2) Inserting and trimming Another approach is to replace the boundaries with comma and then trim off the commas at beginning and end. This one does not require perl regular expressions. Be sure NOT to use perl=TRUE with this. It treats \b differently.
gsub("^,|,$", "", gsub("\\b", ",", x))
## [1] "a,b,c" "a,b,c,d,e" "a,b,c,d,e,1,2,3"
\\K
also works in place of \\b
using perl = TRUE
.
2a) In R 3.6 (but not earlier) trimws
has an argument that allows trimming of arbitrary characters so this can be simplified to:
trimws(gsub("\\b", ",", x), whitespace = ",")
## [1] "a,b,c" "a,b,c,d,e" "a,b,c,d,e,1,2,3"
2b) This variation works even pre-3.6 but assumes that there are no tabs in the strings. It replaces each boundary with a tab, trims whitespace off the ends and then replaces tabs with commas.
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) It seems from the discussion under the question that comma was only an example and whitespace would be just as good as far as the poster is concerned. In that case we could simplify this to:
trimws(gsub("\\b", " ", x))
## [1] "a b c" "a b c d e" "a b c d e 1 2 3"
3) \B Replace non-boundaries with comma like this. Be sure to specify perl regular expressions. This will work if the strings contain alphanumerics but if they contain non-word characters then not.
gsub("\\B", ",", x, perl = TRUE)
## [1] "a,b,c" "a,b,c,d,e" "a,b,c,d,e,1,2,3"