【问题标题】:Why doesn't the match operator match anything?为什么匹配运算符不匹配任何内容?
【发布时间】:2009-11-02 22:45:19
【问题描述】:

我正在尝试解析这个 HTML 块:

<div class="v120WrapperInner"><a href="/redirect?q=http%3A%2F%2Fwww.google.com%2Faclk%3Fsa%3DL%26ai%3DCKJh--O7tSsCVIKeyoQTwiYmRA5SnrIsB1szYhg2d2J_EAhABIJ7rxQ4oA1CLk676B2DJntmGyKOQGcgBAaoEFk_Qyu5ipY7edN5ETLuchKUCHbY4SA#0%26num%3D1%26sig%3DAGiWqtwtAf8NslosN7AuHb7qC7RviHVg7A%26q%3Dhttp%3A%2F%2Fwww.youtube.com%2Fwatch%253Fv%253D91sYT_8CN8Q%2526feature%253Dpyv%2526ad%253D3409309746%2526kw%253Dsusan%25252#0boyle&amp;adtype=pyv&amp;event=ad&amp;usg=bR7ErKA_3szWtQMGe2lt1dpxzHc=" title="The Valley Downs Chicago"><img class="vimg120" alt="The Valley Downs Chicago" src="http://i2.ytimg.com/vi/91sYT_8CN8Q/1.jpg">

捕获重定向链接:

/redirect?q=http%3A%2F%2Fwww.google.com%2Faclk%3Fsa%3DL%26ai%3DCKJh--O7tSsCVIKeyoQTwiYmRA5SnrIsB1szYhg2d2J_EAhABIJ7rxQ4oA1CLk676B2DJntmGyKOQGcgBAaoEFk_Qyu5ipY7edN5ETLuchKUCHbY4SA#0%26num%3D1%26sig%3DAGiWqtwtAf8NslosN7AuHb7qC7RviHVg7A%26q%3Dhttp%3A%2F%2Fwww.youtube.com%2Fwatch%253Fv%253D91sYT_8CN8Q%2526feature%253Dpyv%2526ad%253D3409309746%2526kw%253Dsusan%25252#0boyle&amp;adtype=pyv&amp;event=ad&amp;usg=bR7ErKA_3szWtQMGe2lt1dpxzHc=

和视频标题:

The Valley Downs Chicago

当我使用这个简单的 Perl 代码时:

foreach $_ (@promotedVideos)
{
   if (/\s<div class="v120WrapperInner"><a href="([^"]*)" title="([^"]*)"><img/six)
   {
     print $1;
     print $2;
   }
}

没有打印。在我对此进行故障排除时,我想如果您发现任何错误或有问题的地方,我会问您专家。非常感谢您的帮助!

【问题讨论】:

  • 尝试从你的正则表达式中删除\s
  • 不要使用正则表达式解析 HTML。在 CPAN 上使用出色的 HTML 解析器之一。
  • 尽管我已经支持在非常简单的情况下使用正则表达式解析 HTML,但在这种情况下我会支持思南。那些正则表达式太讨厌了,你只会让自己的生活更加困难。

标签: html perl


【解决方案1】:

您的 /x 正则表达式修饰符将空格弄乱了。删除它。

也就是说,应该是

if (/\s<div class="v120WrapperInner"><a href="([^"]*)" title="([^"]*)"><img/si)

/x 使 perl 忽略正则表达式中的空格,使您的正则表达式等效于以下内容:

/\s<divclass="v120WrapperInner"><a href="([^"]*)"title="([^"]*)"><img/six

那将不匹配。

另外,开头的 \s 可能会导致问题。

这是我用来测试的代码:

use strict;


my $inp = '<div class="v120WrapperInner"><a href="/redirect?q=http%3A%2F%2Fwww.google.com%2Faclk%3Fsa%3DL%26ai%3DCKJh--O7tSsCVIKeyoQTwiYmRA5SnrIsB1szYhg2d2J_EAhABIJ7rxQ4oA1CLk676B2DJntmGyKOQGcgBAaoEFk_Qyu5ipY7edN5ETLuchKUCHbY4SA#0%26num%3D1%26sig%3DAGiWqtwtAf8NslosN7AuHb7qC7RviHVg7A%26q%3Dhttp%3A%2F%2Fwww.youtube.com%2Fwatch%253Fv%253D91sYT_8CN8Q%2526feature%253Dpyv%2526ad%253D3409309746%2526kw%253Dsusan%25252#0boyle&amp;adtype=pyv&amp;event=ad&amp;usg=bR7ErKA_3szWtQMGe2lt1dpxzHc=" title="The Valley Downs Chicago"><img class="vimg120" alt="The Valley Downs Chicago" src="http://i2.ytimg.com/vi/91sYT_8CN8Q/1.jpg">';

print "$inp\n";

if ( $inp =~ /<div class="v120WrapperInner"><a href="([^"]*)" title="([^"]*)"><img/si )
{
 print "m:\n$1\n$2\n";
}

【讨论】:

  • 嗯......这似乎没有什么不同。
  • 我刚刚测试过,效果很好。但我一开始就删除了\s。
  • 完美! “\s”是造成问题的原因。非常感谢!为什么那个“\s”有问题?
  • 因为它在打开尖括号之前需要一个空格。
  • 这是人们不应该盲目做 Perl 最佳实践所说的任何事情的原因之一。如果您不了解匹配运算符选项,请不要使用它们。
【解决方案2】:

好的,这不是您要问的,但我认为(基于这个和您的旧问题)您正在解析 HTML。

让我告诉你:正则表达式不是解决方案。您应该使用HTML::TreeBuilder 来解析 HTML 文档,因为 HTML 文档非常混乱。

#!/usr/bin/perl
use strict;
use warnings;
use HTML::TreeBuilder;

my $root = HTML::TreeBuilder->new_from_file(\*DATA);
foreach my $div ($root->find_by_tag_name('div')) {
    if ($div->attr('class') eq 'v120WrapperInner') {
        foreach (my $a = $div->find_by_tag_name('a')) {
            print "m:\n", $a->attr('href'), "\n", $a->attr('title'), "\n";
        }
    }
}

【讨论】:

    【解决方案3】:

    很高兴您在 perl 中获得了使用正则表达式的经验,但对于此类工作,您可能会考虑使用 DOM 解析器,例如 XML::DOM

    【讨论】:

      【解决方案4】:

      生日,

      如果您在理解正则表达式时遇到问题,我建议您阅读 Dale Dougherty 的优秀著作“sed & awk”(sanitised Amazon link) 中的正则表达式介绍。

      绝对是正则表达式的最佳介绍之一。

      HTH

      干杯,

      【讨论】:

      • 这似乎使用了广告/推荐链接,而不是直接转到amazon.com/dp/1565922255 ?
      • @Peter,哎呀。我深夜的错误。这不是一个完整的推荐链接,因为里面没有 id。我已更改为指向正确的原版链接。
      • 实际上,当我进去查看原始降价时,链接确实实际上指向原版 amazon.com/dp/ISBN-10
      • 嗯,这就是 SO 正在做的事情。 :/ 不知道为什么 - 没有必要屏蔽亚马逊推荐的链接。由于更加愚蠢,我不得不对您的帖子进行虚拟编辑,以便删除之前的否决票。
      • 请停止对这个答案投反对票。现在正在重写链接。请参阅 meta meta.stackexchange.com/questions/26964/…> 上的这篇文章
      猜你喜欢
      • 2010-12-12
      • 1970-01-01
      • 2012-03-12
      • 2013-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-17
      • 2014-12-09
      相关资源
      最近更新 更多