【问题标题】:Perl Delete First OccurrencePerl 删除第一次出现
【发布时间】:2013-08-04 01:14:53
【问题描述】:

好的,我想删除文件中第一次出现的字符串,比如“dog”,并且只删除第一次出现的字符串。因此,如果文件读取:

狗很开心。
这只狗喜欢奔跑。

输出将是

很高兴。
这只狗喜欢奔跑。

我有以下代码:

#!/usr/local/bin/perl

use warnings;
use strict;

my $file = $ARGV[0];
my $out = $ARGV[1];

open (IN, "<$file");
open (OUT, ">$out");
while(<IN>){
  s/dog/ /;
  print OUT $_;
}

close IN;
close OUT;

而且它有效,但它不是只替换第一个实例,而是替换单词的所有实例。我以为我必须使用全局修饰符 g 来使其替换所有实例?为什么它要替换我正在搜索的字符串的所有实例?这可能是一些我没有看到的简单错误。

【问题讨论】:

    标签: perl replace


    【解决方案1】:

    每次评估运算符时它都会替换第一个实例,并且您为每一行评估运算符,因此您替换每行中的第一个实例。如果您使用/g,您将替换每一行中的所有实例。

    my $seen;
    while (<>) {
       ++$seen if !$seen && s/dog//;
       print;
    }
    

    或者作为单行:

    perl -pe'++$seen if !$seen && s/dog//;' infile >outfile
    

    您可以重新添加文件句柄,但以上接受更标准和更灵活的用法。要获得与您的代码相同的效果,您只需使用

    script.pl infile >outfile
    

    而不是

    script.pl infile outfile
    

    【讨论】:

    • @eckes,是的,注意到我误读了这个问题,并在一分钟前修复了它。
    • 效果很好。但要澄清一下,infile >outfile 与 infile outfile 有什么不同?
    • 如果您使用script.pl infile outfile,我的代码会将infileoutfile 都视为输入文件。
    【解决方案2】:

    这可以通过单行来实现:

    perl -0777 -pe 's/dog/ /' inputfile > outputfile
    

    -0777 开关将文件作为单行读取,这将使您的替换按预期工作。这一行就相当于程序文件:

    $/ = undef; 
    $\ = undef;
    while (<>) {
        s/dog/ /;
        print;
    }
    

    【讨论】:

      【解决方案3】:
      while ( <> ) { 
          my $found = s/dog//;
          print;
          last if $found;
      }
      print while <>;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-12-14
        • 2022-11-22
        • 2021-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-25
        • 2015-06-04
        相关资源
        最近更新 更多