【问题标题】:How to Access an Array in Perl for Regex如何在 Perl 中为 Regex 访问数组
【发布时间】:2011-01-29 12:05:03
【问题描述】:

我的命令提示符中有两个输入,第一个是我正在编写的程序要搜索的一系列单词,第二个是包含要找到单词的文件。因此,例如,我的命令提示符读取 perl WebScan.pl word WebPage000.htm

现在,我可以毫无问题地访问这些输入中的任何一个以进行打印,但是我很难访问网页的内容,因此我可以执行正则表达式来删除 html 标签并访问内容。我意识到有一个子程序可以在没有正则表达式的情况下更有效地执行此操作,但我需要使用正则表达式:(。

我可以毫无问题地访问 html 文件进行打印:

open (DATA, $ARGV[1]);
my @file = <DATA>;
print @file;

它打印了 html 页面的整个代码,但我无法传递正则表达式来删除 html 块。我不断收到一条错误消息,上面写着“无法修改 s/// near 中的数组取消引用”,这是我有特定正则表达式的地方。我不知道如何解决这个问题-我尝试将数组转换为标量,但是我根本无法访问 html 中的任何数据(不,它不只是打印数组中的值 :P)

如何访问数组的内容,以便使用正则表达式来优化所需的输出?

【问题讨论】:

  • 我们需要查看正则表达式代码。
  • @codaddict => 你会从perl -e '@array =~ s/.//' 之类的地方得到这个错误,因为在标量上下文中数组返回的值是只读的,所以 perl 会退出。
  • 不要使用 DATA 作为文件句柄名,它是一个特殊的文件句柄。实际上,不要使用全局文件句柄,使用词法文件句柄。使用 open 的 3 参数形式来制作它们。 open my $fh, '&lt;', $ARGV[1] or die "Can't open $ARGV[1]: $!\n";

标签: perl


【解决方案1】:

听起来你正在做类似@file =~ s/find/replace/; 的事情。您收到该错误是因为正则表达式绑定运算符的左侧对其参数施加了标量上下文。标量上下文中的数组返回其长度,但该值是只读的。因此,当您的替换尝试执行替换时,kaboom。

为了处理文件的所有行,您可以使用foreach 循环:

foreach my $line (@file) {$line =~ s/find/replace/}

或者更简洁:

s/find/replace/ for @file;

但是,如果您在 HTML 文件上运行正则表达式,您可能需要它们匹配多行。您在上面所做的是读取整个文件,并将每一行存储为@file 的一个元素。如果您在数组上使用 Perl 的迭代控制结构之一,您将无法匹配多行。因此,您应该改为将文件读入单个标量。然后您可以按预期使用$file =~ s///

您可以通过暂时清除输入记录分隔符$/ 将文件slurp 成单个变量:

my $file = do {local $/; <DATA>};

一般来说,正则表达式是解析 HTML 的错误工具,但听起来这是一个家庭作业,所以在这种情况下,无论如何它只是练习。

最后,在现代 Perl 中,您应该使用 open 的三参数形式以及词法文件句柄和错误检查:

open my $DATA, '<', $ARGV[1] or die "open error: $!";

my $file = do {local $/; <$DATA>};

【讨论】:

  • 太棒了,非常感谢。是的,这是一道家庭作业题,但不幸的是,教授和助教都好心解释如何访问 html 文件。
  • 作为 slurp 的替代方案(特别是如果您需要先下载该页面,但也适用于本地页面),您可以使用 LWP::UserAgent,use LWP::UserAgent; my $ua = LWP::UserAgent-&gt;new(); my $html = $ua-&gt;get($address)-&gt;as_string(); 现在您有了 HTML 源代码标量 $html 中名为 $address 的站点。
猜你喜欢
  • 2013-03-07
  • 2013-03-08
  • 2023-03-08
  • 2014-10-13
  • 2016-12-12
  • 1970-01-01
  • 2013-08-21
  • 1970-01-01
相关资源
最近更新 更多