0

我有一个文件夹,其中包含“n”个 html 文件。我将阅读文件并采取一行。(即)我将<img />标签放在一个数组中并打印该数组。现在不打印数组。你能帮助我吗。我的代码在这里。

use strict;
use File::Basename;
use File::Path;
use File::Copy;
use Win32::OLE;
use Win32::OLE::Const 'Microsoft Excel';

print "Welcome to PERL program\n";

#print "\n\tProcessing...\n";
my $foldername = $ARGV[0];
opendir(DIR,$foldername) or die("Cannot open the input folder for reading\n");
my (@htmlfiles) = grep/\.html?$/i, readdir(DIR);
closedir(DIR);


@htmlfiles = grep!/(?:index|chapdesc|listdesc|listreview|addform|addform_all|pattern)\.html?$/i,@htmlfiles;
# print "HTML file is @htmlfiles";

my %fileimages;
my $search_for = 'img';
my $htmlstr;
for my $files (@htmlfiles)
{
    if(-e "$foldername\\$files")
    {
        open(HTML, "$foldername\\$files") or die("Cannot open the html files '$files' for reading");
        local undef $/;my $htmlstr=<HTML>;
        close(HTML);
        $fileimages{uc($2)}=[$1,$files] while($htmlstr =~/<img id="([^"]*)" src="\.\/images\/[^t][^\/<>]*\/([^\.]+\.jpg)"/gi);

    }
}

在命令提示符下。

perl findtext.pl "C:\viji\htmlfiles"

问候,维吉

4

1 回答 1

4

我想指出用正则表达式解析 HTML 是徒劳的。请参阅史诗https://stackoverflow.com/a/1732454/1521179获得答案。

您用于提取图像标签的正则表达式非常糟糕。您无需使用 HTML 解析器并遍历树,而是搜索一个字符串……</p>

/<img id="([^"]*)" src="\.\/images\/[^t][^\/<>]*\/([^\.]+\.jpg)"/gi
  • 开始于<img
  • 在恰好一个空格之后,id="找到序列。如果找到,则捕获该属性的内容,否则匹配失败。关闭"被消耗。
  • 在恰好一个空格之后,src="./images/找到序列,
  • 后跟一个不是 的字符t。(这当然允许")。
  • 这后面是任意数量的非斜杠或字符的任何<>字符(这再次允许", ),
  • 后跟一个斜线。
  • 现在捕捉这个:
    • 一个或多个不是点的字符
    • 后跟.jpg
  • 之后"必须立即跟进。

误报

这是您的正则表达式将匹配的一些数据,它不应该匹配:

<ImG id="" src="./ImAgEs/s" alt="foo/bar.jpg"

那么你得到的图像路径是什么?./ImAgEs/s" alt="foo/bar.jpg可能不是你想要的。

<!-- <iMg id="" src="./images/./foobar.jpg" -->

糟糕,我匹配了评论的内容。并且该路径不包含./images. 该.文件夹在您的正则表达式中完全有效,但表示同一文件夹。我什至可以使用..,您的 HTML 文件的文件夹是什么。或者我可以使用./images/./t-rex/image.jpg与禁止文件夹匹配的t内容。

假阴性

以下是一些您想要但不会得到的数据:

<img
  id="you-cant-catch-me"
  src='./images/x/awesome.jpg' />

为什么?换行符——但您只允许在参数之间使用单个空格。此外,您不允许使用单引号'

<img src="./images/x/awesome.jpg" id="you-cant-catch-me" />

为什么?我现在有单个空格,但交换了参数。但是这两个片段都表示完全相同的 DOM,因此应该被认为是等效的。

结论

访问http://www.cpan.org/并搜索HTMLand Tree。使用一个模块来解析您的 HTML 并遍历树并提取所有匹配的节点。

另外,在print某处添加一个语句。我发现了一个

 use Data::Dumper;
 print Dumper \%fileimages;

对于调试目的非常有启发性。

于 2012-09-21T09:08:30.070 回答