Perl脚本查找和替换无法正常工作?

时间:2016-10-12 19:58:27

标签: perl replace

我正在尝试在Perl中创建一个脚本来替换给定目录中所有HTML文件中的文本。但是,它不起作用。谁能解释我做错了什么?

my @files = glob "ACM_CCS/*.html";

foreach my $file (@files)
{
    open(FILE, $file) || die "File not found";
    my @lines = <FILE>;
    close(FILE);

    my @newlines;
    foreach(@lines) {
        $_ =~ s/Authors Here/Authors introduced this subject for the first time in this paper./g;
        #$_ =~ s/Authors Elsewhere/Authors introduced this subject in a previous paper./g;
        #$_ =~ s/D4-/D4: Is the supporting evidence described or cited?/g;
        push(@newlines,$_);
    }

    open(FILE, $file) || die "File not found";
    print FILE @newlines;
    close(FILE);
}

例如,我想将“D4-”替换为“D4:是......”等等。谢谢,我会感激任何提示。

1 个答案:

答案 0 :(得分:3)

您正在使用open的两个参数版本。如果$file未以“&lt;”,“&gt;”或“&gt;&gt;”开头,则会以读取文件句柄的形式打开。您无法写入读取文件句柄。要解决此问题,请使用open的三个参数版本:

open my $in, "<", $file or die "could not open $file: $!";
open my $out, ">", $file or die "could not open $file: $!";

另请注意使用词法文件句柄($in)而不是裸字文件句柄(FILE)。与omword文件句柄相比,Lexical文件句柄有许多好处:

  1. 它们是词汇范围而非全局
  2. 当他们超出范围而不是程序结束时,他们会关闭
  3. 它们更容易传递给函数(即您不必使用typeglob引用)。
  4. 您使用它们就像使用裸字文件句柄一样。

    您可能需要考虑的其他事项:

    1. 使用严格的pragma
    2. 使用警告pragma
    3. 一次处理文件行或块,而不是一次性读取所有文件
    4. 使用HTML解析器而不是正则表达式
    5. 使用命名变量而不是默认变量($_
    6. 如果您使用默认变量,请不要将其包含在已经使用的位置(例如s/foo/bar/;而不是$_ =~ s/foo/bar/;
    7. 4号对你正在做的事情可能非常重要。如果您不确定这些HTML文件的格式,那么您可能很容易错过任何内容。例如,"Authors Here""Authors\nHere"对HTML来说意味着相同的东西,但是你的正则表达式会错过后者。您可能想看看XML::Twig(我知道它说的是XML,但它也处理HTML)。这是一个非常容易使用的XML / HTML解析器。