【问题标题】:multiple regex using perl使用 perl 的多个正则表达式
【发布时间】:2015-02-19 07:52:14
【问题描述】:

您好,这个网站已经帮助我多次解决了我在 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";

有什么建议吗?

【问题讨论】:

  • 您能否提供一个示例输入以及预期输出?
  • 旁注,my ($marke) = $content =~ m{data-brand="(.*?)"}gism; 优于 my $marke = $1 if ($content =~ m{data-brand="(.*?)"}gism);

标签: regex perl undef


【解决方案1】:

首先,永远不要使用这样的结构:

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

根据documentation

注意mystateour 的行为被声明修改 修饰符条件或循环构造(例如, my $x if ... )是 不明确的。 my 变量的值可以是 undef,任何以前的 赋值,或者其他任何东西。不要依赖它。未来 perl 的版本可能与 Perl 的版本不同 你试试看。这里是龙。

m// 运算符,当指定 /g 修饰符时 in list context, it returns a list of the substrings matched by any capturing parentheses in the regular expression. 因此,正如@Сухой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 仍然存在。 documentation 说:

这些特殊变量,例如 %+ 哈希和编号匹配 变量($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 大师,也许其他人会扩展/纠正这个答案。

【讨论】:

    猜你喜欢
    • 2012-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多