【问题标题】:How can I extract information from an HTML file using Perl regular expressions?如何使用 Perl 正则表达式从 HTML 文件中提取信息?
【发布时间】:2011-10-17 09:45:52
【问题描述】:

我有两个文件,XML 和一个 HTML,需要从这些文件中提取特定模式的数据。

我的 XML 文件格式很好,我可以使用 readline 读取一行并在标签之间搜索数据。

if($line =~ /\<tag1\>$varvalue\<\/tag1\>/)`

但是,对于我的 HTML,它的代码是我见过的最糟糕的代码之一,文件如下:

<div class="theater">
    <h2>
    <a href="/showtimes/university-village-3" >**University Village 3**</a></h2>
    <div class="address">
        <i>**3323 South Hoover Street, Los Angeles CA 90007 | (213) 748-6321**</i>
    </div>
</div>

<div class="mtitle">
    <a href="/movie/dream-house-2011"  title="Dream House" onmouseover="mB(event, 771204354);"  >**Dream House**</a>
    <span>**(PG-13 , 1 hr. 31 min.)**</span>
</div>

<div class="times">

    **1:00 PM,**
</div>

现在我需要从这个文件中选择以粗体显示的数据。

我可以使用 Perl 正则表达式从这个文件中搜索数据。

【问题讨论】:

标签: html xml regex perl


【解决方案1】:

RegEx match open tags except XHTML self-contained tags

http://www.codinghorror.com/blog/2009/11/parsing-html-the-cthulhu-way.html

Using regular expressions to parse HTML: why not?

当你读完那些回来:)

编辑:要真正解决您的问题,请查看此模块:

http://perlmeme.org/tutorials/html_parser.html

解析 html 文件的一些示例:

#!/usr/local/bin/perl

use HTML::TreeBuilder;

$tree = HTML::TreeBuilder->new;
$tree->parse_file('C:\Users\Stefanos\workspace\HTML_Parser_Test\test.html');

@divs = $tree->find('div');

$tree->delete;

在此示例中,我只是将您的标签用作 .html 文件的主体。 div 存储在 @divs 数组中。由于我不知道您要查找哪个文本,因为 ** 不是元素,所以我无法进一步帮助您..

附:我从来没有使用过这个模块,但我只是在 5 分钟内完成了它,所以解析 html 文件并找到你想要的任何东西并不难..

正则表达式匹配任何特定标签并将内容存储到 $1:

if ($subject =~ m!<tagname[^>]*>(.*?)</tagname>!s) {
    # Successful match
}

虽然当你有嵌套元素时你很快就会意识到这种方法的局限性..

用实际标签替换标签名..例如在你的情况下 i, a, span, div 虽然对于 div 你也会得到第一个 div 的内容,这不是你想要的..

【讨论】:

  • 我希望这对我有帮助...非常感谢@FailedDev
  • 问题是我只需要通过正则表达式来做,而且似乎只有库和解析器才有可能?
  • @typedef1 如果您使用正则表达式,那么您的解决方案只能解决一个非常具体的问题并且很容易中断。为什么使用图书馆如此糟糕?大部分的跑腿工作已经为你完成了。
  • 我的项目的要求......我一直在努力研究不同的东西和组合......虽然我读到连 Jon Skeet 都做不到,但我相信一定有适合我的东西。 @FailedDEv
  • @type - 你有没有和老板谈过并解释说**你不应该用正则表达式解析 HTML - 这是一种非常规语法?并且,如果您使用经过适当测试的库,您将得到它,而如果您编写自己的半途而废的解析器,它很可能会包含错误(相信我),并且调试成本非常高昂复杂的正则表达式?
【解决方案2】:

Parsing XML and HTML using regular expressions is a fool's errand。有许多简单易用的 Perl 模块用于解析 HTML。这是使用HTML::TokeParser::Simple 的东西。我省略了将电影和放映时间与剧院相关联的代码(因为我无意构建适当的输入文件):

#!/usr/bin/env perl

use strict; use warnings;
use HTML::TokeParser::Simple;

my $parser = HTML::TokeParser::Simple->new(handle => \*DATA);

my @theaters;

while (my $div = $parser->get_tag('div')) {
    my $class = $div->get_attr('class');
    next unless defined($class) and $class eq 'theater';

    my %record;

    $record{theater} = $parser->get_text('/a');
    $record{address} = $parser->get_text('/i');

    s{(?:^\s+)|(?:\s+\z)}{} for values %record;

    push @theaters, \%record;
}

use YAML;
print Dump \@theaters;

__DATA__
<div class="theater">
    <h2>
    <a href="/showtimes/university-village-3" >**University Village 3**</a></h2>
    <div class="address">
        <i>**3323 South Hoover Street, Los Angeles CA 90007 | (213) 748-6321**</i>
    </div>
</div>

<div class="mtitle">
    <a href="/movie/dream-house-2011"  title="Dream House" onmouseover="mB(event, 771204354);"  >**Dream House**</a>
    <span>**(PG-13 , 1 hr. 31 min.)**</span>
</div>

<div class="times">

    **1:00 PM,**
</div>

<div class="theater">
    <h2>
    <a href="/showtimes/university-village-3" >**Some other theater*</a></h2>
    <div class="address">
        <i>**1234 South Hoover Street, St Paul, MN 99999 | (999) 748-6321**</i>
    </div>
</div>

输出:

[sinan@macardy]:~/tmp> ./tt.pl
---
- 地址:'**3323 South Hoover Street, Los Angeles CA 90007 | (213) 748-6321**'
  剧院:'**大学村 3**'
- 地址:'**1234 South Hoover Street, St Paul, MN 99999 | (999) 748-6321**'
  剧院:'**其他剧院*'

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2011-06-06
  • 2022-07-20
  • 2016-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多