<a href="http://www.utoronto.ca/gdrs/" title="Rehabilitation Science"> Rehabilitation Science</a>
对于上面的例子,我想同时获取部门名称“康复科学”及其主页url "http://www.utoronto.ca/gdrs/“。
有没有人能推荐一些聪明的正则表达式来帮我完成这项工作?
发布于 2011-06-26 04:22:37
根本没有理由使用正则表达式来做这件事。这里有一个使用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"}
这将以<a>
标记的相关内容作为值,以键的形式返回URL散列。这意味着您将只捕获唯一的URL,而丢弃重复的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]'
。
正则表达式在处理HTML和XML时非常脆弱,因为标记格式太自由了;它们可以在保持有效的情况下改变格式,特别是HTML,它的“正确性”差别很大。如果您不拥有正在解析的文件的生成,那么在使用regex时,您的代码将由生成它的人决定;文件中的简单更改可能会严重破坏这种模式,从而导致持续的维护难题。
解析器,因为它实际上了解文件的内部结构,可以承受这些变化。请注意,我故意创建了一些格式错误的HTML,但是代码并不关心。将解析器版本的简单性与正则表达式解决方案进行比较,并考虑长期可维护性。
发布于 2011-06-25 04:15:52
我建议使用HTML解析器,就像@mrk建议的那样。然后将您得到的结果放入正则表达式搜索器中。我喜欢用Rubular。这将向您显示正则表达式正在捕获的内容,并且可以避免获得不想要的结果。我发现使用正则表达式/http^"+/ works“在这样的情况下是可行的,因为即使没有"www.”,它也会捕获整个url,并且您可以避免捕获引号。
发布于 2011-06-26 00:55:30
如果你正在构建一个爬虫,那么Ruby's Mechanize是一个很好的选择。要获取页面并提取链接:
require 'rubygems'
require 'mechanize'
agent = Mechanize.new
page = agent.get "http://google.com/"
page.links.each do |link|
puts link.href
puts link.text
end
文档和指南(我链接的)列出了很多您可能想要做的事情。使用正则表达式解析HTML (或XML)是出了名的棘手且容易出错。使用完整的解析器(如其他人所建议的)将节省您的精力,并使您的代码更健壮。
https://stackoverflow.com/questions/6471085
复制相似问题