正则表达式从HTML中的标签获取特定信息

时间:2012-03-29 21:45:42

标签: php html regex

我有一个带有标记代码的HTML页面:

<a href="#!/series/3078/series-name">
  <span class="title">This is series # 1</span>
  <span class="info">bla bla bla</span>
</a>

<a href="#!/series/3079/series-name-2">
  <span class="title">This is series # 2</span>
  <span class="info">bla bla bla</span>
</a>

<a href="#!/series/3080/series-name-3">
  <span class="title">This is series # 3</span>
  <span class="info">bla bla bla</span>
</a>

我需要获取“/ series /”之后的数字以及“title”类内部范围的文本。

如何使用PHP上的正则表达式执行此操作?

感谢您的帮助

4 个答案:

答案 0 :(得分:1)

Easy as Pi

这是一个小小的Perl程序,它演示了在非常规则和已知组合的HTML上使用正则表达式是多么容易。

#!/usr/bin/env perl
$_ = do { local $/; <DATA> };    
while ( m!/series/(\d+)!g ) {
    print "Series $1: ";
    if ( m!<span class="title">(.*?)</span>!g ) {
        print $1;
    }
    print "\n";
}    
__END__
<a href="#!/series/3078/series-name">
  <span class="title">This is series # 1</span>
  <span class="info">bla bla bla</span>
</a>

<a href="#!/series/3079/series-name-2">
  <span class="title">This is series # 2</span>
  <span class="info">bla bla bla</span>
</a>

<a href="#!/series/3080/series-name-3">
  <span class="title">This is series # 3</span>
  <span class="info">bla bla bla</span>
</a>

运行时,该程序打印出来:

Series 3078: This is series # 1
Series 3079: This is series # 2
Series 3080: This is series # 3

看看这有多容易?什么都没有。

相同的模式适用于PHP,因为我没有做任何只有Perl而不是PCRE的事情。


另一方面......

构建输入会使这种特殊方法陷入困境并不太难。再说一遍,我也很难弥补这一点,因为我已经在其他地方展示了herehere

人们一直使用文本编辑器编辑HTML。这是完全正常的。当他们这样做时,他们使用正则表达式。这并不是说一个程序是幸运的,而另一个程序在做同样的事情时会受到诅咒。想要在非文本编辑器的不同程序中执行与文本编辑器中完全相同的操作没有任何问题。

然而,对于除了最简单的事情之外的所有事情(比如这个问题,这非常简单),有一个权衡,大多数人问如何做到这一点都无法做到。我对这个悖论here进行了较长时间的讨论。

答案 1 :(得分:0)

此处:( 已编辑!

preg_match_all($links, '/\/series\/([\d]+)\/.*?<span class="title">(.*?)<\/span>/ism', $matches);

var_dump($matches);

希望有所帮助。我建议在PHP中查看DOMDocument。我认为这将是一个更清洁的解决方案。正则表达式往往是丑陋和缓慢的。

答案 2 :(得分:0)

正则表达式是否适合这项工作取决于工作实际是什么。如果你有一个很大的HTML页面或一组它们,并且你想从中提取信息,那么正则表达式可能是合适的。但是,如果您的输入不在您的控制之下,那么正则表达式根本不是您想要的。

无论如何,使用PHP执行此操作的正确方法只是使用DOMDocument::loadHTML解析html,并使用从DOMDocument获取的getElementsByTagName并迭代它。如果你感觉很奇怪,甚至可以使用XPath。除了你真的在正则表达式中编写HTML解析器之外,这总是比正则表达式解析HTML更强大的工具。

答案 3 :(得分:-1)

如果您的标记比您发布的代码段长得多,那么正则表达式就不是一种方法,因为它的计算成本非常高。

(无论如何,你无法用正则表达式完全解析XML。)

我建议您使用XML parser解析标记,以便遍历它所代表的树结构。这样您就可以轻松获得所需的数据。

如果href属性总是看起来像#!/series/XXXX/series-name-2,那么您可以通过简单的字符串解析来访问XXXX