2010-04-07 5 views
1

Bonjour,URL extractibles (à tableau) en Ruby

j'apprends sur l'utilisation de RegEx en Ruby, et avoir touché un point où j'ai besoin d'aide. J'essaie d'extraire 0 à plusieurs URL à partir d'une chaîne.

Ce code J'utilise:

sStrings = ["hello world: http://www.google.com", "There is only one url in this string http://yahoo.com . Did you get that?", "The first URL in this string is http://www.bing.com and the second is http://digg.com","This one is more complicated http://is.gd/12345 http://is.gd/4567?q=1", "This string contains no urls"] 
sStrings.each do |s| 
    x = s.scan(/((http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.[\w-]*)?)/ix) 
    x.each do |url| 
    puts url 
    end 
end 

Voici ce qui est retourné:

http://www.google.com 
http 
.google 
nil 
nil 
http://yahoo.com 
http 
nil 
nil 
nil 
http://www.bing.com 
http 
.bing 
nil 
nil 
http://digg.com 
http 
nil 
nil 
nil 
http://is.gd/12345 
http 
nil 
/12345 
nil 
http://is.gd/4567 
http 
nil 
/4567 
nil 

Quelle est la meilleure façon d'extraire uniquement les URL complètes et non les parties du RegEx?

Répondre

4

Vous pouvez utiliser des groupes de capture anonyme (? ...) au lieu de (...).

Je vois que vous faites cela pour apprendre Regex, mais au cas où vous voulez vraiment extraire des URL à partir d'une chaîne, jetez un oeil à URI.extract, qui extrait les URI d'une chaîne. (require "uri" pour l'utiliser)

1

Vous pouvez créer un groupe non-capturant en utilisant (?:SUB_PATTERN). Voici une illustration, avec quelques simplifications supplémentaires. En outre, puisque vous utilisez l'option /x, profitez-en en présentant votre regex de manière lisible.

sStrings = [ 
    "hello world: http://www.google.com", 
    "There is only one url in this string http://yahoo.com . Did you get that?", 
    "... is http://www.bing.com and the second is http://digg.com", 
    "This one is more complicated http://is.gd/12345 http://is.gd/4567?q=1", 
    "This string contains no urls", 
] 

sStrings.each do |s| 
    x = s.scan(/ 
     https?:\/\/ 
     \w+ 
     (?: [.-]\w+)* 
     (?: 
      \/ 
      [0-9]{1,5} 
      \? 
      [\w=]* 
     )? 
    /ix) 

    p x 
end 

Ceci est bien pour l'apprentissage, mais n'essayez pas vraiment de faire correspondre les URL de cette façon. Il y a des outils pour ça.