# Finding filename from a URL

**URL:** <https://rubytalk.org/t/finding-filename-from-a-url/50982>\
**Category:** ruby-talk\
**Created:** [4 January 2009 16:29 UTC](https://rubytalk.org/t/finding-filename-from-a-url/50982 "2009-01-04T16:29:07Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sam\_Fent](https://avatars.discourse-cdn.com/v4/letter/s/f17d59/32.png) [@Sam\_Fent](https://rubytalk.org/u/Sam_Fent)\
**Post date:** [4 January 2009 16:29 UTC](https://rubytalk.org/t/finding-filename-from-a-url/50982/1 "2009-01-04T16:29:07Z")

</div>

Hi all,

This is just a basic parsing question, really. I'm trying to work out  
how I would process a URL such as  
"[http://www.example.com/x/y/z/myfile.txt](http://www.example.com/x/y/z/myfile.txt)" and get back the filename  
"myfile". Basically the pattern is to get the past part of the string  
after the final /, and then strip off the filetype.

Any help would be much appreciated,  
Thanks!

Sam

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Jan-Erik\_R](https://avatars.discourse-cdn.com/v4/letter/j/45deac/32.png) [@Jan-Erik\_R](https://rubytalk.org/u/Jan-Erik_R)\
**Post date:** [4 January 2009 16:30 UTC](https://rubytalk.org/t/finding-filename-from-a-url/50982/2 "2009-01-04T16:30:37Z")

</div>

Sam Fent schrieb:

> Hi all,
> 
> This is just a basic parsing question, really. I'm trying to work out  
> how I would process a URL such as  
> "[http://www.example.com/x/y/z/myfile.txt&quot](http://www.example.com/x/y/z/myfile.txt&quot); and get back the filename  
> "myfile". Basically the pattern is to get the past part of the string  
> after the final /, and then strip off the filetype.
> 
> Any help would be much appreciated,  
> Thanks!
> 
> Sam

File.basename("[http://www.example.com/x/y/z/myfile.txt&quot;\](http://www.example.com/x/y/z/myfile.txt&quot;%5C))  
works perfectly for urls 😉

---

<div class="post-metadata">

**Author:** ![Tim\_Hunter4](https://avatars.discourse-cdn.com/v4/letter/t/ea5d25/32.png) [@Tim\_Hunter4](https://rubytalk.org/u/Tim_Hunter4)\
**Post date:** [4 January 2009 16:35 UTC](https://rubytalk.org/t/finding-filename-from-a-url/50982/3 "2009-01-04T16:35:24Z")

</div>

Sam Fent wrote:

> Hi all,
> 
> This is just a basic parsing question, really. I'm trying to work out  
> how I would process a URL such as  
> "[http://www.example.com/x/y/z/myfile.txt&quot](http://www.example.com/x/y/z/myfile.txt&quot); and get back the filename  
> "myfile". Basically the pattern is to get the past part of the string  
> after the final /, and then strip off the filetype.
> 
> Any help would be much appreciated,  
> Thanks!
> 
> Sam

$ irb  
irb(main):001:0\> x = "[http://www.example.com/x/y/z/myfile.txt&quot](http://www.example.com/x/y/z/myfile.txt&quot);  
=\> "[http://www.example.com/x/y/z/myfile.txt&quot](http://www.example.com/x/y/z/myfile.txt&quot);  
irb(main):002:0\> File.basename(x)  
=\> "myfile.txt"  
irb(main):003:0\> File.basename(x, '.txt')  
=\> "myfile"

> **···**
>
> --  
> RMagick: [http://rmagick.rubyforge.org/](http://rmagick.rubyforge.org/)

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [4 January 2009 18:04 UTC](https://rubytalk.org/t/finding-filename-from-a-url/50982/4 "2009-01-04T18:04:06Z")

</div>

IMHO it is not a good idea to use a File method for URL's because File.basename has different criteria

irb(main):003:0\> File.basename '[http://test.com/aaa\\bbb.txt&#39](http://test.com/aaa%5C%5Cbbb.txt&#39);  
=\> "bbb.txt"

Although I am not sure whether a backslash is allowed there, this is what I'd do:

irb(main):001:0\> url = '[http://www.example.com/x/y/z/myfile.txt&#39](http://www.example.com/x/y/z/myfile.txt&#39);  
=\> "[http://www.example.com/x/y/z/myfile.txt&quot](http://www.example.com/x/y/z/myfile.txt&quot);  
irb(main):002:0\> name = url[%r{[^/]+\z}]  
=\> "myfile.txt"

Kind regards

&nbsp;&nbsp;robert

> **···**
>
> On 04.01.2009 17:29, Sam Fent wrote:
> 
> > This is just a basic parsing question, really. I'm trying to work out  
> > how I would process a URL such as  
> > "[http://www.example.com/x/y/z/myfile.txt&quot](http://www.example.com/x/y/z/myfile.txt&quot); and get back the filename  
> > "myfile". Basically the pattern is to get the past part of the string  
> > after the final /, and then strip off the filetype.

---

<div class="post-metadata">

**Author:** ![Sam\_Fent](https://avatars.discourse-cdn.com/v4/letter/s/f17d59/32.png) [@Sam\_Fent](https://rubytalk.org/u/Sam_Fent)\
**Post date:** [4 January 2009 18:59 UTC](https://rubytalk.org/t/finding-filename-from-a-url/50982/5 "2009-01-04T18:59:06Z")

</div>

Jan-Erik R. wrote:

> Sam Fent schrieb:
> 
> > Sam
> 
> File.basename("[http://www.example.com/x/y/z/myfile.txt&quot;\](http://www.example.com/x/y/z/myfile.txt&quot;%5C))  
> works perfectly for urls 😉

Thanks a lot! I added ".txt" to the arguments of File.basename to get  
rid of the filetype, but besides that, that was what I was looking for.

Thanks!

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Rob\_Biedenharn1](https://avatars.discourse-cdn.com/v4/letter/r/57b2e6/32.png) [@Rob\_Biedenharn1](https://rubytalk.org/u/Rob_Biedenharn1)\
**Post date:** [4 January 2009 20:46 UTC](https://rubytalk.org/t/finding-filename-from-a-url/50982/6 "2009-01-04T20:46:17Z")

</div>

> > This is just a basic parsing question, really. I'm trying to work out  
> > how I would process a URL such as  
> > "[http://www.example.com/x/y/z/myfile.txt&quot](http://www.example.com/x/y/z/myfile.txt&quot); and get back the filename  
> > "myfile". Basically the pattern is to get the past part of the string  
> > after the final /, and then strip off the filetype.
> 
> IMHO it is not a good idea to use a File method for URL's because File.basename has different criteria
> 
> irb(main):003:0\> File.basename '[http://test.com/aaa\\bbb.txt&#39](http://test.com/aaa%5C%5Cbbb.txt&#39);  
> =\> "bbb.txt"
> 
> Although I am not sure whether a backslash is allowed there, this is what I'd do:
> 
> irb(main):001:0\> url = '[http://www.example.com/x/y/z/myfile.txt&#39](http://www.example.com/x/y/z/myfile.txt&#39);  
> =\> "[http://www.example.com/x/y/z/myfile.txt&quot](http://www.example.com/x/y/z/myfile.txt&quot);  
> irb(main):002:0\> name = url[%r{[^/]+\z}]  
> =\> "myfile.txt"
> 
> Kind regards
> 
> &nbsp;&nbsp;robert

Rather than jump to a Regexp, just use the right tool for the job.

> require 'uri'

=\> true

> u=URI.parse '[http://www.example.com/x/y/z/myfile.txt&#39](http://www.example.com/x/y/z/myfile.txt&#39);

=\> #\<URI::HTTP:0x1cac14 URL:[http://www.example.com/x/y/z/myfile.txt&gt](http://www.example.com/x/y/z/myfile.txt&gt);

> u.path

=\> "/x/y/z/myfile.txt"

> File.basename u.path, '.txt'

=\> "myfile"

-Rob

Rob Biedenharn [http://agileconsultingllc.com](http://agileconsultingllc.com)  
Rob@AgileConsultingLLC.com

> **···**
>
> On Jan 4, 2009, at 1:04 PM, Robert Klemme wrote:
> 
> > On 04.01.2009 17:29, Sam Fent wrote:

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [4 January 2009 21:44 UTC](https://rubytalk.org/t/finding-filename-from-a-url/50982/7 "2009-01-04T21:44:00Z")

</div>

I considered URI as well but what makes your code the "right tool for the job"? Basically you use URI only to extract the path and then use File.basename to get the last bit of the path. But: while the URI path consists of elements separated by "/", File.basename also considers "\\" as delimiter. So IMHO it is by no means "the right tool" - at least not more than using a regular expression which extracts exactly the part needed from the string at hand (and is likely faster as well).

The situation would be different if URI provided a method which returns the last path element but as far as I can see this does not exist.

Kind regards

&nbsp;&nbsp;robert

> **···**
>
> On 04.01.2009 21:46, Rob Biedenharn wrote:
> 
> > On Jan 4, 2009, at 1:04 PM, Robert Klemme wrote:
> > 
> > > On 04.01.2009 17:29, Sam Fent wrote:
> > > 
> > > > This is just a basic parsing question, really. I'm trying to work out  
> > > > how I would process a URL such as  
> > > > "[http://www.example.com/x/y/z/myfile.txt&quot](http://www.example.com/x/y/z/myfile.txt&quot); and get back the filename  
> > > > "myfile". Basically the pattern is to get the past part of the string  
> > > > after the final /, and then strip off the filetype.
> > > 
> > > IMHO it is not a good idea to use a File method for URL's because File.basename has different criteria
> > > 
> > > irb(main):003:0\> File.basename '[http://test.com/aaa\\bbb.txt&#39](http://test.com/aaa%5C%5Cbbb.txt&#39);  
> > > =\> "bbb.txt"
> > > 
> > > Although I am not sure whether a backslash is allowed there, this is what I'd do:
> > > 
> > > irb(main):001:0\> url = '[http://www.example.com/x/y/z/myfile.txt&#39](http://www.example.com/x/y/z/myfile.txt&#39);  
> > > =\> "[http://www.example.com/x/y/z/myfile.txt&quot](http://www.example.com/x/y/z/myfile.txt&quot);  
> > > irb(main):002:0\> name = url[%r{[^/]+\z}]  
> > > =\> "myfile.txt"
> > 
> > Rather than jump to a Regexp, just use the right tool for the job.
> > 
> > \> require 'uri'  
> > =\> true  
> > \> u=URI.parse '[http://www.example.com/x/y/z/myfile.txt&#39](http://www.example.com/x/y/z/myfile.txt&#39);  
> > =\> #\<URI::HTTP:0x1cac14 URL:[http://www.example.com/x/y/z/myfile.txt&gt](http://www.example.com/x/y/z/myfile.txt&gt);  
> > \> u.path  
> > =\> "/x/y/z/myfile.txt"  
> > \> File.basename u.path, '.txt'  
> > =\> "myfile"

---

<div class="post-metadata">

**Author:** ![Rob\_Biedenharn1](https://avatars.discourse-cdn.com/v4/letter/r/57b2e6/32.png) [@Rob\_Biedenharn1](https://rubytalk.org/u/Rob_Biedenharn1)\
**Post date:** [4 January 2009 21:58 UTC](https://rubytalk.org/t/finding-filename-from-a-url/50982/8 "2009-01-04T21:58:04Z")

</div>

> > > > This is just a basic parsing question, really. I'm trying to work out  
> > > > how I would process a URL such as  
> > > > "[http://www.example.com/x/y/z/myfile.txt&quot](http://www.example.com/x/y/z/myfile.txt&quot); and get back the filename  
> > > > "myfile". Basically the pattern is to get the past part of the string  
> > > > after the final /, and then strip off the filetype.
> > > 
> > > IMHO it is not a good idea to use a File method for URL's because File.basename has different criteria
> > > 
> > > irb(main):003:0\> File.basename '[http://test.com/aaa\\bbb.txt&#39](http://test.com/aaa%5C%5Cbbb.txt&#39);  
> > > =\> "bbb.txt"
> > > 
> > > Although I am not sure whether a backslash is allowed there, this is what I'd do:
> > > 
> > > irb(main):001:0\> url = '[http://www.example.com/x/y/z/myfile.txt&#39](http://www.example.com/x/y/z/myfile.txt&#39);  
> > > =\> "[http://www.example.com/x/y/z/myfile.txt&quot](http://www.example.com/x/y/z/myfile.txt&quot);  
> > > irb(main):002:0\> name = url[%r{[^/]+\z}]  
> > > =\> "myfile.txt"
> > 
> > Rather than jump to a Regexp, just use the right tool for the job.  
> > \> require 'uri'  
> > =\> true  
> > \> u=URI.parse '[http://www.example.com/x/y/z/myfile.txt&#39](http://www.example.com/x/y/z/myfile.txt&#39);  
> > =\> #\<URI::HTTP:0x1cac14 URL:[http://www.example.com/x/y/z/myfile.txt&gt](http://www.example.com/x/y/z/myfile.txt&gt);  
> > \> u.path  
> > =\> "/x/y/z/myfile.txt"  
> > \> File.basename u.path, '.txt'  
> > =\> "myfile"
> 
> I considered URI as well but what makes your code the "right tool for the job"? Basically you use URI only to extract the path and then use File.basename to get the last bit of the path. But: while the URI path consists of elements separated by "/", File.basename also considers "\\" as delimiter. So IMHO it is by no means "the right tool" - at least not more than using a regular expression which extracts exactly the part needed from the string at hand (and is likely faster as well).
> 
> The situation would be different if URI provided a method which returns the last path element but as far as I can see this does not exist.
> 
> Kind regards
> 
> &nbsp;&nbsp;robert

I guess it depends on what your url might look like. For example, if it contains a query string:

> str = '[http://a.b.c/root/sub/dir/file?param=a&#39](http://a.b.c/root/sub/dir/file?param=a&#39);

=\> "[http://a.b.c/root/sub/dir/file?param=a&quot](http://a.b.c/root/sub/dir/file?param=a&quot);

> File.basename str

=\> "file?param=a"

Oops! File.basename just doesn't fit.

> require 'uri'

=\> true

> url = URI.parse(str)

=\> #\<URI::HTTP:0x1c8446 URL:[http://a.b.c/root/sub/dir/file?param=a&gt](http://a.b.c/root/sub/dir/file?param=a&gt);

> url.path

=\> "/root/sub/dir/file"

> File.basename url.path

=\> "file"

The OP will have to make the final tool selection, but there may be lurkers that have similar problems who find URI a better fit than File.

-Rob

Rob Biedenharn [http://agileconsultingllc.com](http://agileconsultingllc.com)  
Rob@AgileConsultingLLC.com

> **···**
>
> On Jan 4, 2009, at 4:44 PM, Robert Klemme wrote:
> 
> > On 04.01.2009 21:46, Rob Biedenharn wrote:
> > 
> > > On Jan 4, 2009, at 1:04 PM, Robert Klemme wrote:
> > > 
> > > > On 04.01.2009 17:29, Sam Fent wrote:

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [5 January 2009 17:45 UTC](https://rubytalk.org/t/finding-filename-from-a-url/50982/9 "2009-01-05T17:45:01Z")

</div>

Certainly. I do have to say that I get the impression we are talking a bit past each other. I wasn't advocating to use File.basename at all - not alone and not in combination with URI!

For the URL with query part I would still rather do

name = URI.parse(str).path[%r{[^/]+\z}]

Kind regards

&nbsp;&nbsp;robert

> **···**
>
> On 04.01.2009 22:58, Rob Biedenharn wrote:
> 
> > On Jan 4, 2009, at 4:44 PM, Robert Klemme wrote:
> > 
> > > On 04.01.2009 21:46, Rob Biedenharn wrote:
> > > 
> > > > On Jan 4, 2009, at 1:04 PM, Robert Klemme wrote:
> > > > 
> > > > > On 04.01.2009 17:29, Sam Fent wrote:
> > > > > 
> > > > > > This is just a basic parsing question, really. I'm trying to work out  
> > > > > > how I would process a URL such as  
> > > > > > "[http://www.example.com/x/y/z/myfile.txt&quot](http://www.example.com/x/y/z/myfile.txt&quot); and get back the filename  
> > > > > > "myfile". Basically the pattern is to get the past part of the string  
> > > > > > after the final /, and then strip off the filetype.
> > > > > 
> > > > > IMHO it is not a good idea to use a File method for URL's because File.basename has different criteria
> > > > > 
> > > > > irb(main):003:0\> File.basename '[http://test.com/aaa\\bbb.txt&#39](http://test.com/aaa%5C%5Cbbb.txt&#39);  
> > > > > =\> "bbb.txt"
> > > > > 
> > > > > Although I am not sure whether a backslash is allowed there, this is what I'd do:
> > > > > 
> > > > > irb(main):001:0\> url = '[http://www.example.com/x/y/z/myfile.txt&#39](http://www.example.com/x/y/z/myfile.txt&#39);  
> > > > > =\> "[http://www.example.com/x/y/z/myfile.txt&quot](http://www.example.com/x/y/z/myfile.txt&quot);  
> > > > > irb(main):002:0\> name = url[%r{[^/]+\z}]  
> > > > > =\> "myfile.txt"
> > > > 
> > > > Rather than jump to a Regexp, just use the right tool for the job.  
> > > > \> require 'uri'  
> > > > =\> true  
> > > > \> u=URI.parse '[http://www.example.com/x/y/z/myfile.txt&#39](http://www.example.com/x/y/z/myfile.txt&#39);  
> > > > =\> #\<URI::HTTP:0x1cac14 URL:[http://www.example.com/x/y/z/myfile.txt&gt](http://www.example.com/x/y/z/myfile.txt&gt);  
> > > > \> u.path  
> > > > =\> "/x/y/z/myfile.txt"  
> > > > \> File.basename u.path, '.txt'  
> > > > =\> "myfile"
> > > 
> > > I considered URI as well but what makes your code the "right tool for the job"? Basically you use URI only to extract the path and then use File.basename to get the last bit of the path. But: while the URI path consists of elements separated by "/", File.basename also considers "\\" as delimiter. So IMHO it is by no means "the right tool" - at least not more than using a regular expression which extracts exactly the part needed from the string at hand (and is likely faster as well).
> > > 
> > > The situation would be different if URI provided a method which returns the last path element but as far as I can see this does not exist.
> > > 
> > > Kind regards
> > > 
> > > &nbsp;&nbsp;robert
> > 
> > I guess it depends on what your url might look like. For example, if it contains a query string:
> > 
> > \> str = '[http://a.b.c/root/sub/dir/file?param=a&#39](http://a.b.c/root/sub/dir/file?param=a&#39);  
> > =\> "[http://a.b.c/root/sub/dir/file?param=a&quot](http://a.b.c/root/sub/dir/file?param=a&quot);  
> > \> File.basename str  
> > =\> "file?param=a"
> > 
> > Oops! File.basename just doesn't fit.
> > 
> > \> require 'uri'  
> > =\> true  
> > \> url = URI.parse(str)  
> > =\> #\<URI::HTTP:0x1c8446 URL:[http://a.b.c/root/sub/dir/file?param=a&gt](http://a.b.c/root/sub/dir/file?param=a&gt);  
> > \> url.path  
> > =\> "/root/sub/dir/file"  
> > \> File.basename url.path  
> > =\> "file"
> > 
> > The OP will have to make the final tool selection, but there may be lurkers that have similar problems who find URI a better fit than File.
> 
> --  
> remember.guy do |as, often| as.you\_can - without end
