perl:逐行和整体之间的变化

时间:2014-03-12 17:34:36

标签: perl

我开始使用perl,我需要编辑一些文本。有时我需要perl逐行读取输入,有时我需要perl读取输入作为一个整体。我知道这可以设置为:

$/ = undef;

或类似的东西:

{
        local $/;
        $myfile= <$MYFILE>;
}

但我不知道如果在同一个剧本中我想要改变&#34;整体&#34;到&#34;逐行&#34;或相反亦然。也就是说,假设一个脚本的开头为:

use warnings;
use strict;
my $filename = shift;
open F, $filename or die "Usa: $0 FILENAME\n";
while(<F>) {
}

我做了一些替换(s ///;)。然后我需要继续我的版本,但整体阅读。所以我写道:

{
        local $/;
        $filename = <F>;
}

但是我需要逐行阅读....

有人可以向我解释这背后的逻辑,以便学习如何改变&#39;从一种模式到另一种模式,始终保持输入的最后编辑版本?感谢


好的,抱歉。我将尝试将注意力集中在Y而不是X.例如,我需要编辑一个文本,并仅在由两个单词分隔的文本部分上进行替换。所以想象一下,我想要取代所有形式的&#34; dog&#34;到了#34; cat&#34;,但仅限于那些&#34;狗&#34;这个词在#34;你好&#34;之间。我的意见:

hello
dog
dog
dog
hello
dog
dog

我的输出:

hello
cat
cat
cat
hello
dog

我的剧本:

use warnings;
use strict;
my $file = shift;
open my $FILE, $file or die "Usa: $0 FILENAME\n";
{       
local $/;
$file = <$FILE>;
do {$file =~ s{dog}{cat}g} until
($file =~ m/hello/);
}
print $file;

但我更换了所有&#34;狗&#34;

我尝试了其他策略:

use warnings;
use strict;
my $file = shift;
open my $FILE, $file or die "Usa: $0 FILENAME\n";
{       
local $/;
$file = <$FILE>;
while ($file =~ m{hello(.*?)hello}sg) {
my $text = $1;
$text =~ s{dog}{cat}g;
}
}
print $file;

但在这种情况下,我没有替代......

2 个答案:

答案 0 :(得分:2)

你不必诉诸啜饮和多行正则表达式来解决这个问题。只需使用变量来跟踪当前行的状态,即您是否在分隔符的内部或外部:

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

my $in_hello;
while (<DATA>) {
    chomp;
    $in_hello = ! $in_hello if $_ eq 'hello';
    s/dog/cat/ if $in_hello;
    say;
}

__DATA__
hello
dog
dog
dog
hello
dog
dog

输出:

hello
cat
cat
cat
hello
dog
dog

答案 1 :(得分:1)

默认,逐行,模式再次回到代码块之外:

{
    local $/;
    $filename = <F>;
}

$/是全局变量,在此示例中为dynamically scoped