1
\$\begingroup\$

I finally converted my horrific HTML regex parsing:

if (
    $info =~ /
    Platform\sType<\/td>\n\s+<td><b>(.*?)<\/b>(.*?)<\/td>.*
    Codeset<\/td>\n\s+<td><b><i>(.*?)<\/i>.*
    Status<\/td>\n\s+<td>\n\s+<div(?:.*?)">(.*?)<\/div><br>.*
    Instance\sID<\/td>\n\s+<td>(.*?)<\/td>.*
    Instance\sName<\/td>\n\s+<td>(.*?)<\/td>.*
    Brand<\/td>\n\s+<td><span(?:.*?)">(.*?)<\/span>.*
    Date\sAdded<\/td>\n\s+<td>(.*?)<\/td>.*
    Date\sUsed<\/td>\n\s+<td>(.*?)<\/td>.*
    Date\sModified<\/td>\n\s+<td>(.*?)<\/td>.*
    Flavor\sid<\/td>\n\s+<td>(\d+)<\/td>.*
    Flavor\sname<\/td>\n\s+<td>(.*?)<\/td>.*
    Image\sgroup\sid<\/td>\n\s+<td>(.*?)<\/td>.*
    Image\sid<\/td>\n\s+<td>(.*?)<\/td>.*
    Image\sname<\/td>\n\s+<td>(.*?)<\/td>.*
    Customer\suid<\/td>\n\s+<td><input(?:.*?)value="(.*?)">.*
    Back\sreference<\/td>\n\s+<td><input(?:.*?)value="(.*?)">.*
    HG\sserver\sid<\/td>\n\s+<td><input(?:.*?)value="(.*?)">.*
    HG\sMigration\sState<\/td>\n\s+<td>(?:.*?)<option\sselected="selected">(.*?)<\/option>.*
    HG\sUsed<\/td>(?:.*?)selected="selected">(.*?)<\/option>.*
    HG\slast\smodified<\/td>(?:.*?)value="(.*?)">.*
    Box\sIP<\/td>\n\s+<td\sclass="ping"\sdata-ip="(.*?)">.*
    Box\sHostname<\/td>\n\s+<td>(.*?)\s\(<a.*
    Volumes<\/td>\n\s+<td\svalign="top">\n\s+(.*?)<\/td>.*
    Addons<\/td>\n\s+<td\svalign="top">\n\s+(.*?)<\/td>.*
    Main\sIP<\/td>\n\s+(?:.*?)data-ip="(.*?)"(?:.*?)inline-block">(.*?)<\/div>.*?
    <table\sclass="concise">(.*?)<\/table>
    /xsm
  )
{

To what I hope is the right way of doing things, however, I feel like there could be some improvements.

my $tree = HTML::TreeBuilder->new;
$tree->parse_file($file_name);
$tree->eof();
my $t = Text::ASCIITable->new({headingText => 'HAL Server Report'});
$t->setCols('Field', 'Result');
$t->alignCol({Result => 'left'});
my $table = $tree->look_down(_tag => 'table', class => 'grid');
foreach my $tr ( $tree->look_down(_tag => 'tr') ) {
    last if $tr->look_down(_tag => 'td', class => 'key', sub { $_[0]->as_text() eq 'Meta' });
    my @tmp;
    my $count = 0;
    foreach my $td ( $tr->look_down(_tag => 'td') ) {
        if ( $count < 2 ) {
            if ( $td->look_down(_tag => 'select') ) {
                    my $select = $td->look_down(_tag => 'option', sub { $_[0]->attr('selected') });
                    push @tmp, $select->as_text() if $select;
            } elsif ( $td->look_down(_tag => 'input') ) {
                    my $input = $td->look_down(_tag => 'input', sub { $_[0]->attr('value') });
                    push @tmp, $input->attr_get_i('value') if $input;
            } elsif ( $td->look_down(_tag => 'table', class => 'concise') ) {
                    my @ips;
                    foreach my $td2 ( $td->look_down(_tag => 'tr') ) {
                        my $ip = $td2->look_down(_tag => 'td', sub { $_[0]->attr('data-ip') });
                        push @ips, $ip->attr_get_i('data-ip') if $ip;
                    }
                    push @tmp, join ", ", @ips;
            } else {
                push @tmp, $td->as_trimmed_text();
            }
        }
        $count++;
    }
    if ( $tmp[0] =~ /^([a-zA-Z0-9]+)([ a-zA-Z0-9]+?)$/ ) {
        $t->addRow($tmp[0], $tmp[1]);
    }
}
print $t;
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.