How to replace the space between single letters with a period

Viewed 55

I am trying to replace the space between single letters (initials of names) with a period. There should also be a trailing period after the final letter.

For example:

"h a g wells j g verne" becomes "h.a.g. wells j.g. verne"
and
"h a g wells j g" becomes "h.a.g. wells j.g."

This question Removing spaces between single letters, has got it most of the way but I am struggling to get the trailing period. Could I have some help please.

My efforts

x <- "h a g wells j g verne" 
y <- "h a g wells j g"       

# Almost but need trailing period as well
temp <- gsub("(?<=(?<!\\w)\\w) (?=\\w(?!\\w))", ".", x , perl=TRUE) 
temp
# [1] "h.a.g wells j.g verne"
 
# Trying for the trailing periods
# messes first by matching first letter but okay in second 
gsub("(\\.\\w)", "\\1.", temp) 
# [1] "h.a..g. wells j.g. verne"

# messes first by matching first letter but okay in second 
gsub("(\\w\\.\\w)", "\\1.", temp) 
# [1] "h.a..g wells j.g. verne"

# messes first by matching first letter but okay in second 
gsub("(?<=\\.\\w)", ".", temp, perl=TRUE) 
# [1] "h.a..g. wells j.g. verne"
 
# Success 
temp2 <- gsub("(\\.\\w)\\s", "\\1. ", temp)
temp2
# [1] "h.a.g. wells j.g. verne"
 
# ... but not for y which misses the second trailing period
temp <- gsub("(?<=(?<!\\w)\\w) (?=\\w(?!\\w))", ".", y , perl=TRUE) 
gsub("(\\.\\w)\\s", "\\1. ", temp)  
# [1] "h.a.g. wells j.g"
1 Answers

You can use

x <- c("h a g wells j g verne", "h a g wells j g")
gsub("(?<=\\b\\w) (?=\\w\\b)|(?<=\\b\\w)(?= |$)", ".", x, perl=TRUE)
## => [1] "h.a.g. wells j.g. verne" "h.a.g. wells j.g."  

See the regex demo and the online R demo. Note that (?<!\w)\w = \b\w and (?=\w(?!\w)) = (?=\w\b), that is why I shortened it like that.

To support any whitespace, replace the literal space in the pattern with \\s.

The (?<=\b\w) (?=\w\b)|(?<=\b\w)(?= |$) regex matches

  • (?<=\b\w) (?=\w\b) - a space that is preceded with a word char preceded with a word boundary and is immediately followed with a word char that is followed with a word boundary
  • | - or
  • (?<=\b\w)(?= |$) - a location immediately after a word char that is preceded with a word boundary and is immediately followed with a space or end of string.

If you want to only take letters into account, not any word chars (letter, digits, underscores), you need to use \p{L} instead of \w, that is

gsub("(?<=\\b\\p{L}) (?=\\p{L}\\b)|(?<=\\b\\p{L})(?= |$)", ".", x, perl=TRUE)
Related