72

I'm new at regular expressions and wonder how to phrase one that collects everything after the last /.

I'm extracting an ID used by Google's GData.

my example string is

http://spreadsheets.google.com/feeds/spreadsheets/p1f3JYcCu_cb0i0JYuCu123

Where the ID is: p1f3JYcCu_cb0i0JYuCu123

Oh and I'm using PHP.

Alan Moore
  • 73,866
  • 12
  • 100
  • 156
Hellonearthis
  • 1,664
  • 1
  • 18
  • 26

8 Answers8

136

This matches at least one of (anything not a slash) followed by end of the string:

[^/]+$


Notes:

  • No parens because it doesn't need any groups - result goes into group 0 (the match itself).
  • Uses + (instead of *) so that if the last character is a slash it fails to match (rather than matching empty string).


But, most likely a faster and simpler solution is to use your language's built-in string list processing functionality - i.e. ListLast( Text , '/' ) or equivalent function.

For PHP, the closest function is strrchr which works like this:

strrchr( Text , '/' )

This includes the slash in the results - as per Teddy's comment below, you can remove the slash with substr:

substr( strrchr( Text, '/' ), 1 );
Peter Boughton
  • 110,170
  • 32
  • 120
  • 176
  • 7
    +1 for using non-regex solution. Sub-stringing the URL would faster and would avoid importing regex support. – Jonathon Watney Jul 19 '09 at 19:22
  • Indeed - I suspect most functions for this would work backwards from the end, and so avoid checking most characters. Afaik all regex engines work forwards, so would have to check every character. – Peter Boughton Jul 19 '09 at 19:26
  • 1
    Thanks for the awesome help, I know have a much better understanding of regex. The PHP code looks like this. preg_match('([^/]+$)', "http://spreadsheets.google.com/feeds/spreadsheets/p1f3JYcCu_cb0i0JYuCu124", $matches) – Hellonearthis Jul 19 '09 at 20:04
  • Another +1 for non-regex solution. Much faster. – T.J. Schuck Nov 11 '10 at 01:29
  • 1
    If you'd like to remove the '/' you could do like this; `substr( strrchr( Text, '/' ), 1 );` – Teddy Zetterlund Feb 03 '11 at 21:15
  • Can someone explain why that regex grabs everything after the last slash and not 1st one since ^ is being used. – CodeCrack Jan 20 '12 at 00:13
  • CodeCrack, the `^` is inside a character class (`[..]`) so it does not indicate start of line. Character classes have some different syntax/rules to outside regex - specifically, when it is the first character after the opening bracket, the `^` inverts the class. (So in this instance it means "any character that is not /".) – Peter Boughton Jun 13 '12 at 23:15
  • `[^/]+$` is actually wrong. `/` is a delimiter, you should escape it: `[^\/]+$`. – Thielicious Jun 12 '17 at 12:23
  • Keep in mind that this regex will match the whole string if there is no `/` in it, while the PHP solution will return an empty string in that case. If you don't want the full string to be matched in that edge case then check out [rasjani's solution](https://stackoverflow.com/a/1150597/1494454). – totymedli Dec 01 '20 at 21:37
22

Generally:

/([^/]*)$

The data you want would then be the match of the first group.


Edit   Since you’re using PHP, you could also use strrchr that’s returning everything from the last occurence of a character in a string up to the end. Or you could use a combination of strrpos and substr, first find the position of the last occurence and then get the substring from that position up to the end. Or explode and array_pop, split the string at the / and get just the last part.

Gumbo
  • 643,351
  • 109
  • 780
  • 844
  • 4
    you may need to escape the slash in the character class, depending on the language you're using. `/([^\/]*$/` – rampion Jul 19 '09 at 19:09
  • @rasjani: It depends on the language if you can use that regular expression like I wrote it. Some languages have a syntax literal for regular expressions (like Perl’s `/…/`), others have classes to build one from a string (like Java) and others just use strings (like PHP). But in general my regular expression is correct. – Gumbo Jul 19 '09 at 19:11
  • This would also match "/", which means your group would be empty, i.e. an empty ID. If you don't want that consider /([^/]+)$ instead. – Jonathon Watney Jul 19 '09 at 19:12
  • Thanks Gumbo, that help me a lot too. There heaps of different ways to do things in php. – Hellonearthis Jul 19 '09 at 21:14
13

You can also get the "filename", or the last part, with the basename function.

<?php
$url = 'http://spreadsheets.google.com/feeds/spreadsheets/p1f3JYcCu_cb0i0JYuCu123';

echo basename($url); // "p1f3JYcCu_cb0i0JYuCu123"

On my box I could just pass the full URL. It's possible you might need to strip off http:/ from the front.

Basename and dirname are great for moving through anything that looks like a unix filepath.

James Socol
  • 1,795
  • 10
  • 11
11
/^.*\/(.*)$/

^ = start of the row

.*\/ = greedy match to last occurance to / from start of the row

(.*) = group of everything that comes after the last occurance of /

eyelidlessness
  • 62,413
  • 11
  • 90
  • 94
rasjani
  • 7,372
  • 4
  • 22
  • 35
3

you can also normal string split

$str = "http://spreadsheets.google.com/feeds/spreadsheets/p1f3JYcCu_cb0i0JYuCu123";
$s = explode("/",$str);
print end($s);
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
2

This pattern will not capture the last slash in $0, and it won't match anything if there's no characters after the last slash.

/(?<=\/)([^\/]+)$/

Edit: but it requires lookbehind, not supported by ECMAScript (Javascript, Actionscript), Ruby or a few other flavors. If you are using one of those flavors, you can use:

/\/([^\/]+)$/

But it will capture the last slash in $0.

eyelidlessness
  • 62,413
  • 11
  • 90
  • 94
1

Not a PHP programmer, but strrpos seems a more promising place to start. Find the rightmost '/', and everything past that is what you are looking for. No regex used.

Find position of last occurrence of a char in a string

hughdbrown
  • 47,733
  • 20
  • 85
  • 108
  • I was thinking of doing that, but new preg_match could do it. I'm sure there's better ways to do things, than the ways I end up doing them. – Hellonearthis Jul 19 '09 at 21:17
0

based on @Mark Rushakoff's answer the best solution for different cases:

<?php
$path = "http://spreadsheets.google.com/feeds/spreadsheets/p1f3JYcCu_cb0i0JYuCu123?var1&var2#hash";
$vars =strrchr($path, "?"); // ?asd=qwe&stuff#hash
var_dump(preg_replace('/'. preg_quote($vars, '/') . '$/', '', basename($path))); // test.png
?>
  1. Regular Expression to collect everything after the last /
  2. How to get file name from full path with PHP?
eapo
  • 1,053
  • 1
  • 19
  • 40