繁体   English   中英

如何在Perl中读取多行?

[英]How can I read multiple lines in 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?
}

如果要一次读取所有行,请更改行分隔符$/

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

如果您想一次阅读两行,则可以一次阅读两行。

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

我不确定句子中“不删除换行符”是什么意思,但是要逐行读取文件,您会执行以下操作

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

如果您想一次将所有行读入一个数组,则可以

my @lines = <MYFILE>;

或者要全部读入一个字符串,请将换行符$ /更改为undefined

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

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

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"

根据您的最新评论,我想知道这是否是您想要的:

#!/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";
}

它会将每个选择的双引号(无论多长时间)捕获为一项。 (可以预料:George这是一个解决方案,但是,不,我没有选择使用File::Slurp 。)

您要查找的操作称为“文件读取”,而不是未定义$ /

采用

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' ) ;

听起来好像您想读取文件中的所有“双引号”值,包括跨行拆分的值。 如果是这样,您可以执行以下操作:

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

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

随着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!"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM