Встроенный в Ruby URI полезен для некоторых вещей, но это не лучший выбор при работе с международными символами или адресами IDNA.Для этого я рекомендую использовать Addressable gem.
Вот какой-то очищенный вывод IRB:
require 'addressable/uri'
url = 'http://www.example.com/wp content/uploads/2012/01/München.jpg'
uri = Addressable::URI.parse(url)
Вот что теперь знает Ruby:
#<Addressable::URI:0x102c1ca20
@uri_string = nil,
@validation_deferred = false,
attr_accessor :authority = nil,
attr_accessor :host = "www.example.com",
attr_accessor :path = "/wp content/uploads/2012/01/München.jpg",
attr_accessor :scheme = "http",
attr_reader :hash = nil,
attr_reader :normalized_host = nil,
attr_reader :normalized_path = nil,
attr_reader :normalized_scheme = nil
>
И, глядя на путь, вы можете видеть его как есть или как оно должно быть:
1.9.2-p290 :004 > uri.path # => "/wp content/uploads/2012/01/München.jpg"
1.9.2-p290 :005 > uri.normalized_path # => "/wp%20content/uploads/2012/01/M%C3%BCnchen.jpg"
Адресность действительно должна быть выбрана для замены URI в Ruby, учитывая то, как Интернет переходит на более сложные URI.и смешанные символы Юникода.
Теперь получить строку тоже очень просто, но зависит от того, сколько текста вам нужно просмотреть.
Если у вас полный документ HTML, лучше всегодолжен использовать Nokogiri для анализа HTML и извлечения параметров href
из тегов <a>
.Это то место, с которого нужно начинать отдельный <a>
:
require 'nokogiri'
html = '<a href="http://www.example.com/wp content/uploads/2012/01/München.jpg">München</a>'
doc = Nokogiri::HTML::DocumentFragment.parse(html)
doc.at('a')['href'] # => "http://www.example.com/wp content/uploads/2012/01/München.jpg"
Синтаксический анализ с использованием DocumentFragment
позволяет избежать упаковки фрагмента в обычные теги <html><body>
.Для полного документа, который вы хотите использовать:
doc = Nokogiri::HTML.parse(html)
Вот разница между ними:
irb(main):006:0> Nokogiri::HTML::DocumentFragment.parse(html).to_html
=> "<a href=\"http://www.example.com/wp%20content/uploads/2012/01/M%C3%BCnchen.jpg\">München</a>"
против:
irb(main):007:0> Nokogiri::HTML.parse(html).to_html
=> "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html><body><a href=\"http://www.example.com/wp%20content/uploads/2012/01/M%C3%BCnchen.jpg\">München</a></body></html>\n"
Итак, используйтевторой для полного HTML-документа и для небольшого частичного фрагмента, используйте первый.
Чтобы отсканировать весь документ, извлекая все hrefs, используйте:
hrefs = doc.search('a').map{ |a| a['href'] }
Если выесть только небольшие строки, как показано в вашем примере, вы можете использовать простое регулярное выражение, чтобы выделить необходимые href
:
html[/href="([^"]+)"/, 1]
=> "http://www.example.com/wp content/uploads/2012/01/München.jpg"