Perl嵌套if语句

jon*_*h_w 1 perl

我有这个perl代码,基本上可以读取每一行以找到特定的模式。针对第一条if语句指定的模式,我需要从该模式中提取一些子字符串,因此需要第二条if语句。查看输出,我发现结果不是很正确,两个if的结果之间有些绑定错误。是第二个if从第一行开始读取同一行if吗?如果没有,如何第二秒钟读取同一行if

open(DICT, "<", $file)
or die "Cannot open '$file': $!";
my %h;
while (<DICT>) {
    if (/(<p class="calibre_\d+">\s*?\d+\.\s*?(?:(?!<p).)*<\/p>)/) {
        my $entry = $1;

        if (/<p class="calibre_\d+">\s*?\d+\.\s*?\K([a-zA-Z][a-zA-Z\-_\s'’?“”=…\)()]+[a-zA-Z'\-’])/) {
            my $hw = $1;
            $h{$entry} = $hw;
        }
    }
    END{
        while (my ($k, $v) = each %h) {
            print qq{$v\n$k\n</>\n}
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

源文本文件是这样的:

A
<div class="notes"><p class="calibre_2">  ??</p><p class="calibre_2">  1.abc    ??</p>
</>
Run Code Online (Sandbox Code Playgroud)

结果是这样的:

abc
<p class="calibre_2">  1.abc    ??</p>
</>
Run Code Online (Sandbox Code Playgroud)

也就是说,对于所有标签<p class="calibre_\d+">,如果该标签后面的标签中有一个英文单词\d\.,则将其提取出来,并将其与该单词所在的相应标签链接。

更新:我刚刚意识到,如果我将所有<p class="calibre_\d+">标签分开放在不同的行中,这个问题将消失。最初,所有<p class="calibre_\d+">单词都在同一行中。

因此,新问题应该是:如果这些标签在同一行中,如何分别处理它们?

zdi*_*dim 7

这是一个HTML片段,因此最好使用库进行解析。但是,它并不是一个完全有效的HTML(请注意</>),它会抛出大多数解析器。

我发现Marpa :: HTML甚至可以解析。看到这个帖子,这里的问题起源。

要求是提取特定元素并形成自定义格式的“ 条目 ”,该条目在问题中的“ 预期结果 ”下显示,并在注释中阐明。

use warnings;
use strict;
use feature 'say';

use Marpa::HTML qw(html);   
use utf8;    
use open ':std', ':encoding(UTF-8)';

my $html = <<END_HTML;
A
<div class="notes"><p class="calibre_2"> ??</p><p class="calibre_2"> 1.abc ??</p>
<div class="notes"><p class="calibre_1">7. some calibre_1 as well</p>
</>
END_HTML    #/    
say $html;

my @entries_with_Eng;            
my $new_html = Marpa::HTML::html( \$html, {
    'p' => sub {
        my $attr = Marpa::HTML::attributes();
        if (exists $attr->{class} and $attr->{class} =~ /calibre_[0-9]+/) { #/
            my $cont = Marpa::HTML::contents();
            say "contents: $cont";
            if ($cont =~ /[0-9]+\s*\.\s*([a-zA-Z0-9_\s]+)/) {
                my $entry = "$1\n" . Marpa::HTML::original() . "\n</>";
                push @entries_with_Eng, $entry;
            }
        }
        return;
    },
});

say '';  say for @entries_with_Eng;
Run Code Online (Sandbox Code Playgroud)

注意,我只提取一个简单的选择(ascii \w,并且也留有一个空格,以便也捕获所有这样的单词);请针对您的定义完成“ 英文单词 ”的定义。

如果应该更改HTML字符串(不仅提取了某些数据),而且要通过return在闭包中添加新内容来进行更改,那么处理后的项目以及返回的$new_html字符串(引用)的更改与原始内容有所不同。请参阅模块文档。

以上印刷品

use warnings;
use strict;
use feature 'say';

use Marpa::HTML qw(html);   
use utf8;    
use open ':std', ':encoding(UTF-8)';

my $html = <<END_HTML;
A
<div class="notes"><p class="calibre_2"> ??</p><p class="calibre_2"> 1.abc ??</p>
<div class="notes"><p class="calibre_1">7. some calibre_1 as well</p>
</>
END_HTML    #/    
say $html;

my @entries_with_Eng;            
my $new_html = Marpa::HTML::html( \$html, {
    'p' => sub {
        my $attr = Marpa::HTML::attributes();
        if (exists $attr->{class} and $attr->{class} =~ /calibre_[0-9]+/) { #/
            my $cont = Marpa::HTML::contents();
            say "contents: $cont";
            if ($cont =~ /[0-9]+\s*\.\s*([a-zA-Z0-9_\s]+)/) {
                my $entry = "$1\n" . Marpa::HTML::original() . "\n</>";
                push @entries_with_Eng, $entry;
            }
        }
        return;
    },
});

say '';  say for @entries_with_Eng;
Run Code Online (Sandbox Code Playgroud)