【问题标题】:How to store file content sentence by sentence in an array如何将文件内容逐句存储在数组中
【发布时间】:2014-07-14 21:20:07
【问题描述】:

我想打开一个文件,并将其内容存储在一个数组中,并一次更改每个句子,然后打印文件的输出。

我有这样的事情:

open (FILE , $file);
my @lines = split('.' , <FILE>)
close FILE;
for (@lines) {
s/word/replace/g;
}
open (FILE, ">$file");
print FILE @lines;
close FILE;

由于某种原因,perl 不喜欢这样并且不会将任何内容输出到新文件中。似乎不喜欢我拆分数组。有人可以解释一下为什么 perl 会这样做以及可能的解决方法吗?谢谢!

【问题讨论】:

  • 建议有效
  • 脚本的第二行缺少分号(;),这是错误。
  • 谢谢,从下面的答案中,我的错误是我需要添加 split('\.' , );反而。我现在唯一的问题是,当我打印出文件时,所有句点都被删除了。任何想法如何解决这一问题?再次感谢!
  • @user3646369:使用join ('.',@lines )

标签: perl file


【解决方案1】:

split 需要一个正则表达式。将split('.' , &lt;FILE&gt;) 更改为split(/\./ , &lt;FILE&gt;)

【讨论】:

  • 谢谢!这行得通!在我进行修复后,一切正常,除了现在当我打印输出文件时,所有句点都丢失了,我认为当你拆分数组时会发生这种情况,有没有办法重新制作数组,让句点恢复原位?也许是连接功能?
  • 使用join ('.',@lines )
  • 如果连续有两个句号怎么办...?
【解决方案2】:

my @lines = split('.' , &lt;FILE&gt;) 更改为my @lines = split('\.' , &lt;FILE&gt;)

在正则表达式中仅使用. 来匹配单个字符。所以你需要转义. 才能在句号上拆分。

【讨论】:

    【解决方案3】:
    #!/usr/local/bin/perl
    use strict;
    use warnings;
    my $filename = "somefile.txt";
    my $contents = do { local(@ARGV, $/) = $filename; <> };
    my @lines = split '\.', $contents;
    foreach(@lines){
    #lines is an array which contains one sentence at each index.    
    }
    

    【讨论】:

      【解决方案4】:

      我发现你的脚本的第二行缺少分号(;),这是错误,而且你的脚本无法处理整个文件的内容。它只会处理一行。所以请在下面找到脚本的修改。如果有任何澄清,请告诉我。

      my $file='test.txt';#input file name
      open (FILE , $file);
      #my @lines = split('\.' ,<FILE>); this will not process the entire content of the file.
      my @lines;
      while(<FILE>) {
      s/word/replace/g;
      push(@lines,$_);
      }
      close FILE;
      open (FILE, ">$file");
      print FILE @lines;
      close FILE;
      

      【讨论】:

      • 感谢您的回答,我理解您的意思,但我的脚本在我的 @lines 之后包含更多内容,这迫使它评估数组中的每个元素。我唯一的问题是,一旦我打印文件,整个 txt 中的所有句点都会被删除。你的解决方案能解决这个问题吗?我尝试实现它,但它似乎没有工作
      • 所有的句点是什么?你是说文件的内容?
      • @ThiyaguATR 不,他的意思是句号。分裂吃掉了他们。
      • 如果我输入分号并执行查询,它工作正常。但它只处理第一行。这就是我接近我的方法的原因。我的 $file='test.txt';打开(文件,$文件);我的@lines = split('.' , );关闭文件;打印@行; for (@lines) { s/word/replace/g; #print "$_"; } 打开 (文件, ">$file");打印文件@行;关闭文件;
      【解决方案5】:

      你的代码有很多问题。

      • my @lines = split('.' , &lt;FILE&gt;) 只会读取第一行并将其拆分。
      • split('.' 应该是 split(/\./
      • my @lines = split('.' , &lt;FILE&gt;) 没有分号终止符。
      • print FILE @lines; - 你已经失去了所有的句号!

      最后我想知道,当你只是替换一个单词时,你为什么会为“句子”而烦恼。如果你真的想一次读一个句子(大概是做某种基于句子的处理),那么你需要更改记录分隔符变量$\。例如:

      #!/usr/bin/perl
      
      use strict;
      use warnings;
      
      my $file = "data.txt";
      open (FILE , $file);
      my @buffer;
      $/ = '.';  # Change the Input Separator to read one sentence at a time.
                 # Be careful though, it won't work for questions ending in ?
      while ( my $sentence = <FILE> ) {
         $sentence =~ s/word/replace/g;
         push @buffer, $sentence;
      }
      close FILE;
      
      .. saving to file is left for you to solve.
      

      但是,如果您只想更改字符串,则可以通过将 $/ 设置为 undef 一口气读取整个文件。例如:

      #!/usr/bin/perl
      
      use strict;
      use warnings;
      
      my $file = "data.txt";
      open (FILE , $file);
      $/ = undef; # Slurp mode!
      my $buffer = <FILE>;
      close FILE;
      $buffer =~ s/word/replace/g;
      open (FILE, ">$file");
      print FILE $buffer;
      close FILE;
      

      如果您真的想要处理句子并且想要得到问题,那么您可能想要吞下整个文件然后拆分它,但在您的正则表达式中使用捕获,这样您就不会丢失标点符号。例如:

      !/usr/bin/perl
      
      use strict;
      use warnings;
      
      my $file = "data.txt";
      open (FILE , $file);
      $/ = undef; # slurp!
      my $buffer = <FILE>;
      close FILE;
      
      open (FILE, ">$file" . '.new');  # Don't want to overwrite my input.
      foreach my $sentence (split(/([\.|\?]+)/, $buffer))  # split uses () to capture punctuation.
      {
         $sentence =~ s/word/replace/g;
         print FILE $sentence;
      }
      
      close FILE;
      

      【讨论】:

      • 嘿约翰,对不起,我是提交问题的新手,不想把我的整个脚本放在问题中,因为我认为我的问题很简单,但似乎我需要提供更多上下文对于我的问题。我应该在新线程上重新提出问题吗?我的脚本使用 File::Find 遍历选定的 txt 文件目录,找到一个特定的字符串,如果该字符串出现在句子的末尾或开头,则将其替换为另一个字符串(这取决于用户决定声明的内容)
      • 不,没关系。我猜你可能正在做一些比简单的单词替换更复杂的事情。尝试更改 $/ 而不是使用 split。干净多了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多