我正在尝试创建一个正则表达式模式来提取html中包含href属性中特定关键字的A标签。
例如,如果我有一个HTML块,例如:
<p>Lorem ipsum dolar site amet <a href="http://foo.com">a link</a>. Ut enim ad minim veniam, quis nostrud <a href="http://bar.com">another Link</a>.
如果href属性包含关键字“foo”,如何提取整个A标记(a link)?
非常感谢任何建议!
答案 0 :(得分:3)
除了极其微不足道的用途,regular expressions are discouraged for parsing or manipulating HTML and/or XML。原因是HTML和XML可能会有很大差异,并且仍然有效,导致代码中的正则表达式以新的和奇妙的方式中断,成为维护nightmare。
除了简单的app之外,你应该如何做到这一点:
require "nokogiri"
html = '
<p>Lorem ipsum dolar site amet <a href="http://foo.com">link 1</a>. Ut enim ad minim veniam, quis nostrud <a href="http://bar.com">another Link</a>.</p>
<p>Lorem ipsum dolar site amet <a href="http://bar.com">another link</a>. Ut enim ad minim veniam, quis nostrud <a href="http://foo.com">link 2</a>.</p>
<p>
Lorem ipsum dolar site amet <a href="http://bar.com">another link</a>.
Ut enim ad minim veniam, quis nostrud <a href="http://foo.com">link 3</a>.
</p>
<p>
Lorem ipsum dolar site amet <a href="http://foo.com">link 4</a>.
Ut enim ad minim veniam, quis nostrud <a href="http://bar.com">another Link</a>.
</p>
<p>
Lorem ipsum dolar site amet <a
href="http://foo.com"
>link 5</a>.
Ut enim ad minim veniam, quis nostrud <a href="http://bar.com">another Link</a>.
</p>
'
doc = Nokogiri::HTML(html)
puts doc.search('//a[contains(@href, "foo")]').map{ |n| n.to_s }
>> <a href="http://foo.com">link 1</a>
>> <a href="http://foo.com">link 2</a>
>> <a href="http://foo.com">link 3</a>
>> <a href="http://foo.com">link 4</a>
>> <a href="http://foo.com">link 5</a>
请注意,解析器能够找到所需的<a>
的所有五个匹配项,即使我故意破坏了最后一个。那种受损的格式是有效的,浏览器在理解它时没有任何问题,但想象一下你试图生成一个可以捕获所有这些变化的模式的乐趣。
另请注意,尽管我在href中找到了一个小的XPath技巧来找到嵌入的foo
,但结果代码比正则表达式更容易阅读。我已经做了很长时间了,写了很多正则表达式,并且在接近30年之后,这些东西仍然伤害了我的眼睛。
而且,为了避免您认为这只是一个简单的例子,我在野外遇到了许多HTML和XML文件。这是一个丛林,有一些真正的动物产生内容。
答案 1 :(得分:2)
试试这个:
/<\s*a[^>]+href\s*=\s*"[^"]*foo[^"]*"[^>]*>.*?<\s*\/a\s*>/
这应该可以做到!
答案 2 :(得分:1)
您是否考虑过使用Nokogiri?
答案 3 :(得分:1)
如果你必须使用正则表达式试试这个:
<a\s+href="(?=[^"]*foo)([^"]*)">([^<]*)
我在网上尝试过:rubular.com
我正在使用前瞻来查找它是否包含foo。然后,URL位于第一组中,“a link”位于组2中。
答案 4 :(得分:0)
这应该有效:
(<a[^>]{0,}?href="([^"]{0,}foo[^"]{0,})"[^>]{0,}>[^<]+</a>)
将捕获整个标记和href内容。