5

I know this question has been asked multiple times in different ways, but I can't find a solution where I would replace the text between some "borders" while keeping the borders.

input <- "this is my 'example'"
change <- "test"

And now I want to replace everything between teh single quotes with the value in change.

Expected output would be "this is my 'test'

I tried different variants of:

stringr::str_replace(input, "['].*", change)

But it doesn't work. E.g. the one above gives "this is my test", so it doesn't have the single quotes anymore.

Any ideas?

deschen
  • 10,012
  • 3
  • 27
  • 50

3 Answers3

3

You can use

stringr::str_replace_all(input, "'[^']*'", paste0("'", change, "'"))
gsub("'[^']*'", paste0("'", change, "'"), input)

Or, you may also capture the apostophes and then use backreferences, but that would look uglier (cf. gsub("(')[^']*(')", paste0("\\1",change,"\\2"), input)).

See the R demo online:

input <- "this is my 'example'"
change <- "test"
stringr::str_replace_all(input, "'[^']*'", paste0("'", change, "'"))
gsub("'[^']*'", paste0("'", change, "'"), input)

Output:

[1] "this is my 'test'"
[1] "this is my 'test'"

Note: if your change variable contains a backslash, it must be doubled to avoid issues:

stringr::str_replace_all(input, "'[^']*'", paste0("'", gsub("\\", "\\\\", change, fixed=TRUE), "'"))
gsub("'[^']*'", paste0("'", gsub("\\", "\\\\", change, fixed=TRUE), "'"), input)
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Thanks, but this gives an error: `Error in "'" + change : non-numeric argument to binary operator`, I guess it's because of the + signs. – deschen Nov 22 '22 at 15:13
  • @deschen Just fixed this. Was playing with a different language. – Wiktor Stribiżew Nov 22 '22 at 15:16
  • @deschen I hoped that `change` does not contain substrings like `\1` or `\2` that need to be treated literally. In case they do, see the note I added at the bottom. See [this demo](https://ideone.com/DsLDu5) to better understand what I mean. – Wiktor Stribiżew Nov 22 '22 at 15:25
  • Why are you using `gsub()` if the OP only expects one occurrence in single quotes? – Tim Biegeleisen Nov 22 '22 at 15:33
  • Thanks. It works now, although I decided for this ozther solution from @wace since I don't need to do teh pasting of my `change` with quotes. – deschen Nov 22 '22 at 15:45
  • And no, the text won't contain substrings like \1 or \2. – deschen Nov 22 '22 at 15:46
  • @deschen Note that in case of replacing multiple substrings, `(?<=').*?(?=')` won't work. You must consume the quotes in order to match the right strings between quotes, and not the strings between quoted substrings. – Wiktor Stribiżew Nov 22 '22 at 17:15
  • Ok, but in my case there will just be one string/substring. It actually is a written file path in single quotes that I want to replace by sth. else, and I won‘t have a case where there are several things put into quotes. But understood that the accepted solution won‘t work if there are multiple such strings. – deschen Nov 22 '22 at 19:45
3

Using sub() we can try:

input <- "this is my 'example'"
change <- "test"
output <- sub("'.*?'", paste0("'", change, "'"), input)
output

[1] "this is my 'test'"
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
3

And this way?

input <- "this is my 'example'"
change <- "test"

stringr::str_replace(input, "(?<=').*?(?=')", change)

(?<=') ← look the character before is a ' without catching it.
. ← catch any characters but as less as possible. To covert a case like "this is my 'example' did you see 'it'"
(?=') ← look the character following is a ' without catching it.

↓ Tested here ↓

ideone