我有这个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+">单词都在同一行中。因此,新问题应该是:如果这些标签在同一行中,如何分别处理它们?
这是一个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)
| 归档时间: |
|
| 查看次数: |
173 次 |
| 最近记录: |