Alex
Alex

Reputation: 4995

Rearrange a character string

I have a character vector where some entries have a certain pattern at the end. I want to remove this pattern from the end and put it in front of the rest.

Example:

#My initial character vector
names <- c("sdadohf abc", "fsdgodhgf abc", "afhk xyz")
> names
[1] "sdadohf abc"   "fsdgodhgf abc" "afhk xyz" 

#What I want is to move "abc" to the front
> names
[1] "abc sdadohf"   "abc fsdgodhgf" "afhk xyz" 

Is there an easy way to achive this or do I have to write an own function?

Upvotes: 2

Views: 2397

Answers (3)

rock321987
rock321987

Reputation: 11032

Use this

sub("(.*) \\b(abc)$", "\\2 \\1", names)

.* is a greedy match. It will match as much as it can before finding the string ending with abc.

.* is in first captured group(\\1)

abc is in second captured group(\\2)

We can just interchange their position using \\2 \\1 to find our resultant string

Upvotes: 1

akrun
akrun

Reputation: 887028

Here is a split method. We split the 'names' by one or more space (\\s+) followed by 'abc' ((?=abc)), loop through the list with vapply, reverse (rev) the list elements and paste it together.

vapply(strsplit(names, "\\s+(?=abc)", perl=TRUE), function(x)
                paste(rev(x), collapse=" "), character(1))
#[1] "abc sdadohf"   "abc fsdgodhgf" "afhk xyz"      "abc aksle"   

data

names <- c("sdadohf abc", "fsdgodhgf abc", "afhk xyz", "aksle   abc")

Upvotes: 1

Rich Scriven
Rich Scriven

Reputation: 99331

First let's add one more string to your vector, one with multiple spaces between the text.

names <- c("sdadohf abc", "fsdgodhgf abc", "afhk xyz", "aksle   abc")

You could use capturing groups in sub().

sub("(.*?)\\s+(abc)$", "\\2 \\1", names)
# [1] "abc sdadohf"   "abc fsdgodhgf" "afhk xyz"      "abc aksle"     

Regex explanation courtesy of regex101:

  • (.*) 1st Capturing group - matches any character (except newline) between zero and unlimited times, as few times as possible, expanding as needed
  • \\s+ matches any white space character [\r\n\t\f ] between one and unlimited times, as many times as possible, giving back as needed
  • (abc) 2nd Capturing group - abc matches the characters abc literally, and $ asserts position at end of the string

When we swap the groups in "\\2 \\1", we bring the second capturing group abc to the beginning of the string.

Thanks to @Jota and @docendodiscimus for helping to improve my original regular expression.

Upvotes: 4

Related Questions