Parsing youtube url

I wrote a ruby ​​youtube url url parser. It is designed to enter the URL input of one of the following structures (currently I can find the youtube URL structures, maybe there are more?):

http://youtu.be/sGE4HMvDe-Q http://www.youtube.com/watch?v=Lp7E973zozc&feature=relmfu http://www.youtube.com/p/A0C3C1D163BE880A?hl=en_US&fs=1 

The goal is to save only the ID of the clip or playlist so that it can be embedded, so if it is a clip: 'sGE4HMvDe-Q' , or if it is a playlist: 'p/A0C3C1D163BE880A'

The parser I wrote works fine for these URLs, but it seems a bit fragile and lanky, I'm just wondering if anyone can suggest a more convenient ruby ​​approach to this problem?

 def parse_youtube a = url.split('//').last.split('/') b = a.last.split('watch?v=').last.split('?').first.split('&').first if a[1] == 'p' url = "p/#{b}" else url = b end end 
+8
url ruby ruby-on-rails
source share
3 answers
 def parse_youtube url regex = /(?:.be\/|\/watch\?v=|\/(?=p\/))([\w\/\-]+)/ url.match(regex)[1] end urls = %w[http://youtu.be/sGE4HMvDe-Q http://www.youtube.com/watch?v=Lp7E973zozc&feature=relmfu http://www.youtube.com/p/A0C3C1D163BE880A?hl=en_US&fs=1] urls.each {|url| puts parse_youtube url } # sGE4HMvDe-Q # Lp7E973zozc # p/A0C3C1D163BE880A 

Depending on how you use it, you may need to more carefully verify that the URL is actually on youtube.

UPDATE

Returning to this a few years later. It always annoyed me how careless the original answer was. Since the validity of the Youtube domain has not been verified in any way, I deleted the slop part.

 NODE EXPLANATION -------------------------------------------------------------------------------- (?: group, but do not capture: -------------------------------------------------------------------------------- . any character except \n -------------------------------------------------------------------------------- be 'be' -------------------------------------------------------------------------------- \/ '/' -------------------------------------------------------------------------------- | OR -------------------------------------------------------------------------------- \/ '/' -------------------------------------------------------------------------------- watch 'watch' -------------------------------------------------------------------------------- \? '?' -------------------------------------------------------------------------------- v= 'v=' -------------------------------------------------------------------------------- | OR -------------------------------------------------------------------------------- \/ '/' -------------------------------------------------------------------------------- (?= look ahead to see if there is: -------------------------------------------------------------------------------- p 'p' -------------------------------------------------------------------------------- \/ '/' -------------------------------------------------------------------------------- ) end of look-ahead -------------------------------------------------------------------------------- ) end of grouping -------------------------------------------------------------------------------- ( group and capture to \1: -------------------------------------------------------------------------------- [\w\/\-]+ any character of: word characters (az, AZ, 0-9, _), '\/', '\-' (1 or more times (matching the most amount possible)) -------------------------------------------------------------------------------- ) end of \1 
+19
source share

Using the Addressable gem, you can save yourself some work. There is also a URI in stdlib, but Addressable is more powerful.

 require 'addressable/uri' uri = Addressable::URI.parse(youtube_url) if uri.path == "/watch" uri.query_values["v"] if uri.query_values else uri.path end 

EDIT | Madness removed. Didn't notice that Addressable provides #query_values already.

+4
source share
 require 'uri' require 'cgi' urls = %w[http://youtu.be/sGE4HMvDe-Q http://www.youtube.com/watch?v=Lp7E973zozc&feature=relmfu http://www.youtube.com/p/A0C3C1D163BE880A?hl=en_US&fs=1] def parse_youtube url u = URI.parse url if u.path =~ /watch/ p CGI::parse(u.query)["v"].first else p u.path end end urls.each { |url| parse_youtube url } #=> "/sGE4HMvDe-Q" #=> "Lp7E973zozc" #=> "/p/A0C3C1D163BE880A" 
+4
source share

All Articles