4

嗨,这个网站已经帮助我几次解决我在 perl 中的问题。这是我第一次不得不问一个问题,因为我在谷歌和堆栈溢出上都找不到答案。

我要做的是获取两个单词之间的内容。但他们必须匹配的模式正在发生变化。我正在尝试获取产品详细信息。品牌、描述、名称等。我试图一个接一个地进行正则表达式匹配,但不幸的是这不起作用,因为 $1 保持定义。尝试取消定义 $1 变量会给我错误消息“只读”,这是合乎逻辑的。我将在下面发布我的代码,也许有人有一个如何使其工作的想法。

#!/usr/bin/perl
use strict;
use warnings;
use LWP::Simple;
use IO::File;
use utf8;
my $nfh = IO::File->new('test.html','w');
my $site = 'http://www.test.de/dp/';
my $sku = '1550043196';
my $url = join('',$site,$sku);
my $content = get $url;
my $name = $1 if ($content =~ m{<span id="productTitle" class="a-size-large">(.*?)</span>}gism);
print "$name\n";

# My attempt of undefying 
#undef $1;

my $marke = $1 if ($content =~ m{data-brand="(.*?)"}gism);
print "$marke\n";

有什么建议么?

4

1 回答 1

5

首先,切勿使用以下构造:

my $var = $val if( $some );

根据文档

注意:使用语句修饰符条件或循环构造(例如,my $x if ...)修改的mystateour的行为是未定义的。my变量的值可能是undef,任何先前分配的值,或者可能是其他任何值。不要依赖它。未来版本的 perl 可能会做一些与您尝试使用的 Perl 版本不同的事情。这里是龙。

m//运算符,当在列表上下文/g中指定修饰符时,它返回与正则表达式中的任何捕获括号匹配的子字符串的列表。因此,正如@Сухой27 在上面的评论中所说,您应该使用:

my ($some) = $str =~ m/...(...).../g;

举个简单的例子:

use strict;
use warnings;

my $u="undefined";
my $str = q{some="string" another="one"};

#will match
my ($m1) = $str =~ m/some="(.*?)"/g;
print 'm1=', $m1 // $u, '= $1=', $1 // $u, "=\n";

#will NOT match
my ($m2) = $str =~ m/nothere="(.*?)"/g;
print 'm2=', $m2 // $u, '= $1=', $1 // $u, "=\n";

#will match another
my ($m3) = $str =~ m/another="(.*?)"/g;
print 'm3=', $m3 // $u, '= $1=', $1 // $u, "=\n";

印刷:

m1=string= $1=string=
m2=undefined= $1=string=   #the $1 hold previously matched value
m3=one= $1=one=

如您所见,$1匹配不成功时的剩余部分。文档说:

这些特殊变量,如 %+ 散列和编号匹配变量($1$2$3等)是动态范围的,直到封闭块结束或直到下一个成功匹配,以先到者为准。(请参阅 perlsyn 中的复合语句。)

注意:Perl 中失败的匹配不会重置匹配变量,这使得编写测试一系列更具体情况并记住最佳匹配的代码变得更容易。

因此,如果您不想$1定义,您可以将匹配部分包含在一个块中,例如:

use strict
use warnings;

my $u="undefined";
my $str = q{some="string" another="one"};
my($m1,$m2,$m3);

{($m1) = $str =~ m/some="(.*?)"/g;}
print 'm1=', $m1 // $u, '= $1=', $1 // $u, "=\n";

{($m2) = $str =~ m/nothere="(.*?)"/g;}
print 'm2=', $m2 // $u, '= $1=', $1 // $u, "=\n";

{($m3) = $str =~ m/another="(.*?)"/g;}
print 'm3=', $m3 // $u, '= $1=', $1 // $u, "=\n";

打印什么

m1=string= $1=undefined=
m2=undefined= $1=undefined=
m3=one= $1=undefined=

PS:我不是 Perl 大师,也许其他人会扩展/纠正这个答案。

于 2015-02-19T09:29:24.413 回答