Нет никаких причин использовать регулярные выражения для этого вообще. Вот решение, использующее Nokogiri , который является обычным анализатором Ruby HTML / XML:
html = <<EOT
<p><a href="http://www.example.com/foo">foo</a></p>
<p><a href='http://www.example.com/foo1'>foo1</p></a>
<p><a href=http://www.example.com/foo2>foo2</a></p>
<p><a href = http://www.example.com/bar>bar</p>
<p><a
href="http://www.example.com/foobar"
>foobar</a></p>
<p><a
href="http://www.example.com/foobar2"
>foobar2</p>
EOT
require 'nokogiri'
doc = Nokogiri::HTML(html)
links = Hash[
*doc.search('a').map { |a|
[
a['href'],
a.content
]
}.flatten
]
require 'pp'
pp links
# >> {"http://www.example.com/foo"=>"foo",
# >> "http://www.example.com/foo1"=>"foo1",
# >> "http://www.example.com/foo2"=>"foo2",
# >> "http://www.example.com/bar"=>"bar",
# >> "http://www.example.com/foobar"=>"foobar",
# >> "http://www.example.com/foobar2"=>"foobar2"}
Возвращает хэш URL-адресов в виде ключей со связанным содержимым тега <a>
в качестве значения. Это означает, что вы будете захватывать только уникальные URL, выбрасывая дубликаты. Если вы хотите, чтобы все URL использовали:
links = doc.search('a').map { |a|
[
a['href'],
a.content
]
}
, что приводит к:
# >> [["http://www.example.com/foo", "foo"],
# >> ["http://www.example.com/foo1", "foo1"],
# >> ["http://www.example.com/foo2", "foo2"],
# >> ["http://www.example.com/bar", "bar"],
# >> ["http://www.example.com/foobar", "foobar"],
# >> ["http://www.example.com/foobar2", "foobar2"]]
Я использовал CSS-аксессор 'a'
, чтобы найти теги. Я мог бы использовать 'a[href]'
, если бы хотел захватывать только ссылки, игнорируя якоря.
Regex очень хрупки при работе с HTML и XML, потому что форматы разметки слишком свободны; Они могут различаться по своему формату, оставаясь при этом действительными, особенно HTML, который может сильно различаться по своей «правильности». Если вы не владеете генерацией анализируемого файла, тогда ваш код зависит от того, кто сгенерирует его при использовании регулярных выражений; Простое изменение в файле может сильно испортить схему, что приведет к постоянной головной боли при обслуживании.
Парсер, потому что он на самом деле понимает внутреннюю структуру файла, может противостоять этим изменениям. Обратите внимание, что я намеренно создал какой-то искаженный HTML, но код не заботился. Сравните простоту версии синтаксического анализатора с решением регулярных выражений и подумайте о долговременной поддержке.