【问题标题】:How can I extract the date from this HTML table?我怎样才能提取此HTML表格的日期?
【发布时间】:2012-03-26 05:47:26
【问题描述】:

我正在尝试使用正则表达式从表中的第二个单元格中获取“日期”, 但它不匹配,我真的不知道为什么。

my $str = '"    
    <td class="fieldLabel" height="18">Activation Date:</td>
    <td class="dataEntry" height="18">
        10/27/2011      
    </td>';

if ( $str =~ /Activation Date.*<td.*>(.*)</gm ) {
    print "matched: ".$1;
}else{
    print "mismatched!";
}

【问题讨论】:

  • @JRFerguson:我想我也在那里客串了 :-)
  • @PlatinumAzure:确实你做到了,我喜欢你的回答。没有理由的禁止和警告没有任何教益。问候!

标签: regex perl parsing


【解决方案1】:

其他人已经指出您希望/s 选项使. 匹配换行符,以便您可以使用.* 跨越逻辑行边界。你可能还想要非贪婪的.*?

use v5.10;

my $html = <<'HTML';    
    <td class="fieldLabel" height="18">Activation Date:</td>
    <td class="dataEntry" height="18">
        10/27/2011      
    </td>
HTML

my $regex = qr|
    <td.*?>Activation \s+ Date:</td>
        \s*
    <td.*?class="dataEntry".*?>\s*
        (\S+)
    \s*</td>
    |xs;
    
if ( $html =~ $regex ) {
    say "matched: $1";
    }
else {
    say "mismatched!";
    }

(2020 年更新)但我会使用 Mojo::DOM 和 CSS 选择器来获取日期。特定的选择器可能依赖于完整的 HTML 源代码,但思路是一样的:

use v5.10;

use Mojo::DOM;
use Mojo::Util qw(trim);

my $html = <<'HTML';
    <td class="fieldLabel" height="18">Activation Date:</td>
    <td class="dataEntry" height="18">
        10/27/2011
    </td>
HTML

my $dom = Mojo::DOM->new( $html );
my $date = trim( $dom->at( 'td.dataEntry' )->all_text );

say "Date is $date";

如果你有完整的表格,使用知道如何解析表格的东西会更容易。让诸如 There's also HTML::TableParser 之类的模块处理所有细节:

use v5.10;

my $html = <<'HTML';
    <table>
    <tr>
    <td class="fieldLabel" height="18">Activation Date:</td>
    <td class="dataEntry" height="18">
        10/27/2011      
    </td>
    </tr>
    </table>
HTML

use HTML::TableParser;
  
sub row {
    my( $tbl_id, $line_no, $data, $udata ) = @_;
    return unless $data->[0] eq 'Activation Date';
    say "Date is $data->[1]";
    }
 
# create parser object
my $p = HTML::TableParser->new( 
    { id => 1, row => \&row, } 
    { Decode => 1, Trim => 1, Chomp => 1, } 
    );
$p->parse( $html );

还有HTML::TableExtract:

use v5.10;

my $html = <<'HTML';
    <table>
    <tr>
    <td class="fieldLabel" height="18">Activation Date:</td>
    <td class="dataEntry" height="18">
        10/27/2011      
    </td>
    </tr>
    </table>
HTML

use HTML::TableExtract;
  
my $p = HTML::TableExtract->new;
$p->parse( $html );
my $table_tree = $p->first_table_found;
my $date = $table_tree->cell( 0, 1 );
$date =~ s/\A\s+|\s+\z//g;
say "Date is $date";

【讨论】:

    【解决方案2】:

    您可能误解了正则表达式标志。

    • /m 表示您可能会尝试匹配多行,方法是确保 ^ 可以表示一行的开头,$ 可以表示一行的结尾。
    • /s 意味着您希望通过允许 . 表示任何字符(包括换行符)来将多行表达式视为单行表达式。通常,. 表示任何字符除了换行符。

    如果您添加/s 标志,您的正则表达式应该可以工作,尽管you really shouldn't parse HTML with regex anyway

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-12
      • 1970-01-01
      相关资源
      最近更新 更多