Tyler Rinker
Tyler Rinker

Reputation: 109844

Remove last occurrence of character

A question came across talkstats.com today in which the poster wanted to remove the last period of a string using regex (not strsplit). I made an attempt to do this but was unsuccessful.

N <- c("59.22.07", "58.01.32", "57.26.49")

#my attempts:
gsub("(!?\\.)", "", N)
gsub("([\\.]?!)", "", N)

How could we remove the last period in the string to get:

[1] "59.2207" "58.0132" "57.2649"

Upvotes: 16

Views: 10233

Answers (4)

flodel
flodel

Reputation: 89057

Maybe this reads a little better:

gsub("(.*)\\.(.*)", "\\1\\2", N)
[1] "59.2207" "58.0132" "57.2649"

Because it is greedy, the first (.*) will match everything up to the last . and store it in \\1. The second (.*) will match everything after the last . and store it in \\2.

It is a general answer in the sense you can replace the \\. with any character of your choice to remove the last occurence of that character. It is only one replacement to do!

You can even do:

gsub("(.*)\\.", "\\1", N)

Upvotes: 24

Rich Scriven
Rich Scriven

Reputation: 99331

I'm sure you know this by now since you use stringi in your packages, but you can simply do

N <- c("59.22.07", "58.01.32", "57.26.49")

stringi::stri_replace_last_fixed(N, ".", "")
# [1] "59.2207" "58.0132" "57.2649"

Upvotes: 6

Rohit Jain
Rohit Jain

Reputation: 213223

You need this regex: -

[.](?=[^.]*$)

And replace it with empty string.

So, it should be like: -

gsub("[.](?=[^.]*$)","",N,perl = TRUE)

Explanation: -

[.]         // Match a dot
(?=         // Followed by
    [^.]    // Any character that is not a dot.
     *      // with 0 or more repetition
     $      // Till the end. So, there should not be any dot after the dot we match.
)  

So, as soon as a dot(.) is matched in the look-ahead, the match is failed, because, there is a dot somewhere after the current dot, the pattern is matching.

Upvotes: 17

Dinre
Dinre

Reputation: 4216

I'm pretty lazy with my regex, but this works:

gsub("(*)(.)([0-9]+$)","\\1\\3",N)

I tend to take the opposite approach from the standard. Instead of replacing the '.' with a zero-length string, I just parse the two pieces that are on either side.

Upvotes: 2

Related Questions