r – Replace a part of string based on regex match

The problem is that \1 refers to the first capture group but in the code in the question
there are three capture groups and the replacement string there never refers to \2 or \3. Instead do it like this.

Also if we only expect one substitution in the string use sub rather than gsub.

The third one uses a zero length expression. See ?regex for info.

sub("(2021|2022|2023)", "\\1-", mystring)
## [1] "12312022-273qeq"

# or
sub("(202[123])", "\\1-", mystring)
## [1] "12312022-273qeq"

# or
sub("(?<=202[123])", "-", mystring, perl = TRUE)
## [1] "12312022-273qeq"

To use the pattern in the question use the following replacement string:

sub("(2021)|(2022)|(2023)", "\\1\\2\\3-", mystring)
## [1] "12312022-273qeq"

If we knew that the insertion should always be between the 8th and 9th characters then we could do this:

library(stringi)
mystring_out <- mystring
stri_sub(mystring_out, 9, 8) <- "-"
mystring_out
## [1] "12312022-273qeq"

# or
with(read.fwf(textConnection(mystring), c(8, 99)), paste(V1, V2, sep = "-"))
## [1] "12312022-273qeq"


Note

mystring <- '12312022273qeq'

Read more here: Source link