perl从模式之间的文本文件中获取多行

时间:2014-06-29 17:47:45

标签: regex perl

我有一个html文件,其中包含我必须推送到MySql数据库的数据。我尝试解析html文件以获得我在标量中需要的值,但是当我到达我需要收集数据时,我需要收集的数据不是来自单行文本而是某些模式之间有多行。 到目前为止,这是我所得到的:

  #!/usr/bin/perl
  binmode STDOUT,':encoding(cp1250)';

  open FILE, "index.html" or die "Could not open $file: $!";
  my $word;
  my $description;
  my $origin;

  while (my $line = <FILE>)
  { 
    if ($line =~ m/(?<=<h2 class=\"featured\">)(.*)(?=<\/h2>)/)
    {
    $word = $line =~ m/<=<h2 class=\"featured\">(.*)<\/h2>/;
    $word = $1;     
    }

    if ($line =~ m/(?<=<h4 class=\"related-posts\">)/)
    {
    print $line;
    $origin = $line =~ m/<h4 class=\"related-posts\"> <a href=\"..\/tag\/lacina\/index.html\" rel=\"tag\">(.*)<\/a><\/h4>/;
    $origin = $1;       
    }


  }

print "$word \n";
print "$origin";

现在我想抓住几行文字 - 不必在一个标量中,但我不知道会有多少行。我所知道的是线条介于:

之间
<div class="post-content">

<p>text I want</p>
<p>1.text I want</p>
<p>2.text I want</p>

<div class="box small arial">

另外我想摆脱

       <p>'s

我想读一条线,将它存放在一个标尺中,读取另一条线并与最近保存的标量进行比较。但是我如何支持检查我在标量中是否有我想要的全部内容?

2 个答案:

答案 0 :(得分:1)

使用range operator查找两种模式之间的文字:

use strict;
use warnings;

while (<DATA>) {
    if (my $range = /<div class="post-content">/ .. /<div class="box small arial">/) {
        next if $range =~ /E/;
        print;
    }
}

__DATA__
<html>
<head><title>stuff</title></head>
<body>
<div class="post-content">
<p>text I want</p>
<p>1.text I want</p>
<p>2.text I want</p>
</div>
<div class="box small arial">
</div>
</body>
</html>

输出:

<div class="post-content">
<p>text I want</p>
<p>1.text I want</p>
<p>2.text I want</p>
</div>

然而,真正的答案是使用实际的HTML Parser来解析HTML。

我建议Mojo::DOM。如需有用的8分钟介绍性视频,请查看Mojocast Episode 5

use strict;
use warnings;

use Mojo::DOM;

my $data = do {local $/; <DATA>};

my $dom = Mojo::DOM->new($data);

for my $div ($dom->find('div[class=post-content]')->each) {
    print $div->all_text();
}

__DATA__
<html>
<head><title>stuff</title></head>
<body>
<div class="post-content">
<p>text I want</p>
<p>1.text I want</p>
<p>2.text I want</p>
</div>
<div class="box small arial">
</div>
</body>
</html>

输出:

text I want 1.text I want 2.text I want

答案 1 :(得分:1)

使用工具代替正则表达式。

use strict;
use warnings;
use feature 'say';
use HTML::TreeBuilder;

my $tr = HTML::TreeBuilder->new_from_file('index.html');

for my $div ($tr->look_down(_tag => 'div', 'class' => 'post-content')) {
  for my $t ($div->look_down(_tag => 'p')) {
    say $t->as_text;
  }
}

输出

text I want 1.text I want 2.text I want