0

I'm working with stringr, but the solution doesn't have to be. In the following string I want to replace all the spaces that have a letter to their left and right (i.e. first 2) with underscores.

str = 'ab cd ef 29 17 2 3'

stringr's replace_all don't seem to support substring matching (like str_match_all do by enclosing with (...)). And str_match_all doesn't replace. Grateful for suggestions.

3 Answers 3

4

Use gsub function with lookaround based regex.

> str = 'ab cd ef 29 17 2 3'
> gsub("(?<=[A-Za-z])\\s+(?=[A-Za-z])", "_",str, perl=T)
[1] "ab_cd_ef 29 17 2 3"

OR

> gsub("[A-Za-z]\\K\\s+(?=[A-Za-z])", "_",str, perl=T)
[1] "ab_cd_ef 29 17 2 3"

OR

> library(stringr)
> str_replace_all('ab cd ef 29 17 2 3', perl('(?<=[A-Za-z])\\s+(?=[A-Za-z])'), '_')
[1] "ab_cd_ef 29 17 2 3"
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, this works. For some reason stringr can't handle it and returns an invalid expression error for some reason.
yep, you must need to define the perl option when lookaround based regex is used.
2
(?<=[a-zA-Z])[ ](?=[a-zA-Z])

This should do it for you.Lookbehind will make sure you have letter behind space.

And lookahead will make sure you have a letter ahead of it.See demo.

https://regex101.com/r/zM7yV5/9

1 Comment

Thanks for the demo vks, that's a handy site.
1

Here's another possibility:

gsub("([[:alpha:]])(\\s+)([[:alpha:]])", "\\1_\\3", x)

## "ab_cd_ef 29 17 2 3"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.