1

按照我的另一个问题在这里..

我有以下一段代码,我在其中逐行读取网页的内容,尝试匹配某个模式,如果匹配,则将其写入文件:

foreach my $line (split qr/\R/, $mech->content) {
    if ($line=~ m/t\/([A-Z]+)/){
        print $fileHandle "$1\n";
    }
}

我想知道是否可以将匹配行附加到另一个多行变量并仅在循环完成时将其写入文件。

我希望这样的原因是因为我想使用以下子例程将数据保存到文件中,而不是直接执行:

writeToFile("fileName.tmp","path",data);

这是我编写的一个子程序,除了将数据保存在文件中之外,还检查以下内容:

  1. 指定的路径是否已经存在(如果需要,创建它)
  2. 如果该文件已存在于磁盘上,请将其与即将写入的文件进行比较(并且仅在文件不同时才写入)

因此,如果我能够创建这个额外的变量,我将少一个文件写入磁盘。

4

3 回答 3

4
  1. 您可以通过字符串连接来做到这一点,在您的循环中,您只需将 print 替换为

    $data .= "$1\n"; 
    # Same as $data = $data . "$1\n";
    
  2. 或者使用 Perl 的魔力map来构建多行字符串,而无需循环或if

    my $data = join "", 
                    map { /t\/([A-Z]+)/ ? "$1\n" : "" } 
                    split(qr/\R/, $mech->content);
    
  3. 或者,您甚至不必经历分裂和加入的痛苦。

    只需将多行字符串视为单个字符串(/g修饰符让正则表达式一次又一次地匹配),然后用 3 行替换整个循环:

    my $data = $mech->content();
    $data =~ s/t\/([A-Z]+)/$1\n/g;
    writeToFile("fileName.tmp", "path", $data);
    
于 2013-03-28T20:17:22.120 回答
1

这很简单 - 您可以使用.=运算符(组合赋值 ( =) 和连接 ( .) 来附加字符:

my $data = "";
while (my $line = ...) {
    ...
    $data .= $line . "\n";
}
writeToFile("fileName.tmp", "path", $data);
于 2013-03-28T20:13:58.650 回答
1

只需更换

open(my $fileHandle, ...) or ...;

...

   print $fileHandle "$1\n";

my $data = '';

...

   $data .= "$1\n";

将输出附加到字符串而不是将其发送到文件句柄。

于 2013-03-28T20:19:23.320 回答