R: Find the last dot in a string
Solution 1:
Does this work for you?
x <- "hello.world.123.456"
g <- regexpr("\\.[^\\.]*$", x)
g
-
\.
matches a dot -
[^\.]
matches everything but a dot -
*
specifies that the previous expression (everything but a dot) may occur between 0 and unlimited times -
$
marks the end of the string.
Taking everything together: find a dot that is followed by anything but a dot until the string ends. R requires \
to be escaped, hence \\
in the expression above. See regex101.com to experiment with regex.
Solution 2:
How about a minor syntax improvement?
This will work for your literal example where the input vector is of length 1. Use escapes to get a literal "." search, and reverse the result to get the last index as the "first":
rev(gregexpr("\\.", x)[[1]])[1]
A more proper vectorized version (in case x
is longer than 1):
sapply(gregexpr("\\.", x), function(x) rev(x)[1])
and another tidier option to use tail instead:
sapply(gregexpr("\\.", x), tail, 1)
Solution 3:
Someone posted the following answer which I really liked, but I notice that they've deleted it:
regexpr("\\.[^\\.]*$", x)
I like it because it directly produces the desired location, without having to search through the results. The regexp is also fairly clean, which is a bit of an exception where regexps are concerned :)
Solution 4:
There is a slick stri_locate_last
function in the stringi
package, that can accept both literal strings and regular expressions.
To just find a dot, no regex is required, and it is as easy as
stringi::stri_locate_last_fixed(x, ".")[,1]
If you need to use this function with a regex, to find the location of the last regex match in the string, you should replace _fixed
with _regex
:
stringi::stri_locate_last_regex(x, "\\.")[,1]
Note the .
is a special regex metacharacter and should be escaped when used in a regex to match a literal dot char.
See an R demo online:
x <- "hello.world.123.456"
stringi::stri_locate_last_fixed(x, ".")[,1]
stringi::stri_locate_last_regex(x, "\\.")[,1]