如何在Perl中读取多行?

时间:2009-09-25 21:02:05

标签: perl

我只想读取文件中的多行。例如在sample.txt

"Hi, how are you?"
"Hello 

I'm
fine, thank you!"

现在我的问题是如何在不删除句子中的换行符的情况下阅读第二个语句?

编辑:

似乎我的问题不明确。所以我想我应该编辑这个: 在我上面的例子中,我需要得到整体,

"Hello 

I'm
fine, thank you!"
while ($line = <PFILE>)
{
   #How can I get the statement to $line?
}

7 个答案:

答案 0 :(得分:6)

如果您想一次阅读所有行,请更改行分隔符$/

{
    local $/;  # change the line separator to undef
    $filecontents = <FILE>;
}

如果你想一次读两行,你一次只能读两行。

$lines1_and_2 = <FILE>;
$lines1_and_2 .= <FILE>;

答案 1 :(得分:3)

我不确定你的意思是'在没有删除换行符'的句子中,但是要逐行读取文件,你会做类似的事情

open MYFILE, "<", "MyFile.txt"; # The < is for read mode
while ($line = <MYfILE>) {
    foo($line); #do whatever, one line at a time
}

如果您想一次读取所有行到数组中,您可以

my @lines = <MYFILE>;

或者在一个字符串中全部读取,将换行符分隔符$ /更改为未定义

{
local $/; #initialized to undef
$file = <MYFILE>;
}

答案 2 :(得分:3)

编辑:我想我终于明白了这个问题:

OP有一个文件,由于缺乏更好的术语,它包含问题和答案。问题总是在回答之前出现。两种类型的语句都用双引号括起来。问题及其相关响应之间有一个空行(即"\n\n")。 OP希望逐个阅读问题及其相关答案(不是逐行)。

有几种方法(不一定是啜食)。一种是假设双引号不出现在感兴趣的字符串的开头或结尾之外的任何地方。我不确定这是多么有效的假设,这使得以下脚本变得脆弱。请注意,最后一个块无效,因为答案没有用双引号括起来。

#!/usr/bin/perl

use strict;
use warnings;

while (
    defined(my $q = read_statement(\*DATA))
        and defined(my $a = read_statement(\*DATA))
) {
    print "QUESTION: $q\nANSWER: $a\n\n";
}

sub read_statement {
    my ($fh) = @_;

    my $line;
    while ( $line = <$fh> ) {
        last if $line =~ /^"/;
    }
    return unless defined $line;
    return $line if $line =~ /"$/;

    my $statement = $line;
    while ($line = <$fh> ) {
        $statement .= $line;
        last if $line =~ /"$/;
    }
    return unless $statement =~ /"$/;
    return $statement;
}

测试输入:

__DATA__
"Hi how are you?"
"Hello

im
fine, thank you!"

"How is the weather?"

"It rained
all week.


It's been
gray

    and cold since the 15th"

"Who are you?"

Sinan

输出:

C:\Temp> t
QUESTION: "Hi how are you?"

ANSWER: "Hello

im
fine, thank you!"


QUESTION: "How is the weather?"

ANSWER: "It rained
all week.


It's been
gray

    and cold since the 15th"

答案 3 :(得分:3)

根据您的上一条评论,我想知道这是否是您想要的:

#!/usr/bin/env perl
use strict;
use warnings;
use Text::Balanced qw/extract_delimited/;

my $filecontents = do { local $/; <> };

while (my $item = extract_delimited($filecontents, '"')) {
    print "Item: $item\n";
}

它用双引号将每个选项捕获为一个项目,无论多长。 (预测:乔治这是一个解决方案,但是,不,我没有选择使用File::Slurp。)

答案 4 :(得分:1)

您正在寻找的操作称为“文件啜食” 而不是取消$ /

使用

File::Slurp - 有效阅读/撰写完整档案

这是网站的摘要

  use File::Slurp;

  my $text = read_file( 'filename' ) ;
  my @lines = read_file( 'filename' ) ;

  write_file( 'filename', @lines ) ;

  use File::Slurp qw( slurp ) ;

  my $text = slurp( 'filename' ) ;

答案 5 :(得分:1)

听起来你想要阅读文件中的所有“双引号”值,包括那些跨行分割的值。如果是这种情况,您可以执行以下操作:

my $content = join "", <>;
my @statements = ();
push @statements, $1 while $content =~ /"(.*?)"/msg;

这不会处理引用值中的转义双引号,但您的示例中没有任何示例。如果您需要能够转义引号,则需要稍微更改正则表达式或使用Text :: Balanced,如上所述。

答案 6 :(得分:1)

随着OP的澄清,他试图从文件中获取引用的字符串,并假设每个字符串的结束引用将在一行的末尾,我的方法是:

#!/usr/bin/perl

use strict;
use warnings;

local $/ = qq("\n);    # Extra " to fix SO syntax highlighting

while (my $quot_text = <DATA>) {
  print "Next text:\n$quot_text\n"
}

__DATA__
"Hi how are you?"
"Hello 

im
fine, thank you!"

返回:

Next text:
"Hi how are you?"

Next text:
"Hello

im
fine, thank you!"