Как извлечь информацию из файла HTML с помощью регулярных выражений Perl? - PullRequest
0 голосов
/ 16 октября 2011

У меня есть два файла, 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 для поиска данных из этого файла.

Ответы [ 2 ]

6 голосов
/ 16 октября 2011

RegEx соответствует открытым тегам, за исключением автономных тегов XHTML

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

Использование регулярных выражений для разбора HTML: почему бы и нет?

Когда вы закончите читать, те вернутся:)

Редактировать: и чтобы действительно решить вашу проблему, взгляните на этот модуль:

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.Поскольку я понятия не имею, какой текст вы хотите найти, потому что ** не является элементом, я не могу вам помочь в дальнейшем ..

PS Я никогда не использовал этот модуль, но я сделал это всего за 5 минут, поэтомуне так сложно разобрать html-файл и найти то, что вы хотите ..

Регулярное выражение для соответствия любому конкретному тегу и хранилищу содержимого приводит к $ 1:

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

Хотя вы скороосознайте ограничения этого подхода, когда у вас есть вложенные элементы ..

Замените тэг на фактический тэг .. например, в вашем случае i, a, span, div, хотя для div вы также получите содержимое первого divчто не то, что вы хотите ..

0 голосов
/ 17 октября 2011

Разбор XML и HTML с использованием регулярных выражений - это глупое поручение .Существует много простых в использовании модулей 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
---
- address: '**3323 South Hoover Street, Los Angeles CA 90007 | (213) 748-6321**'
  theater: '**University Village 3**'
- address: '**1234 South Hoover Street, St Paul, MN 99999 | (999) 748-6321**'
  theater: '**Some other theater*'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...