简体   繁体   English

如何在Perl中读取多行?

[英]How can I read multiple lines in Perl?

I just want to read multiple lines in a file. 我只想读取文件中的多行。 For example in sample.txt 例如在sample.txt中

"Hi, how are you?"
"Hello 

I'm
fine, thank you!"

Now my problem is how can I read the second statement without removing the newline in the sentence? 现在我的问题是如何在不删除句子中换行符的情况下阅读第二条语句?

EDIT: 编辑:

It seems that my questions are not clear. 看来我的问题不清楚。 So I think I should edit this: In my examples above, I need to get the whole, 因此,我认为我应该对此进行编辑:在上面的示例中,我需要获取全部信息,

"Hello 

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

If you want to read all lines at once, change the line-separator $/ : 如果要一次读取所有行,请更改行分隔符$/

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

if you want to read two lines at a time you can just read two lines at a time. 如果您想一次阅读两行,则可以一次阅读两行。

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

I'm not sure what you mean by 'without removing the newline' in the sentence, but to read a file, line by line, you would do something like 我不确定句子中“不删除换行符”是什么意思,但是要逐行读取文件,您会执行以下操作

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

If you want to read all lines at once into an array, you can just 如果您想一次将所有行读入一个数组,则可以

my @lines = <MYFILE>;

Or to read it all in one string, change the newline separator $/ to be undefined 或者要全部读入一个字符串,请将换行符$ /更改为undefined

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

EDIT: I think I finally understand the question: 编辑:我想我终于明白了这个问题:

The OP has a file which, for lack of better terminology, contains questions and responses. OP有一个文件,由于缺乏更好的术语,因此包含问题和答案。 Questions always come before responses. 问题总是在回应之前出现。 Both types of statements are enclosed in double quotes. 两种类型的语句都用双引号引起来。 There is a blank line (ie "\\n\\n" ) between a question and its associated response. 问题及其关联的响应之间有一个空白行(即"\\n\\n" )。 The OP wants to read the questions and their associated responses one-by-one (not line-by-line). OP希望一对一(而不是逐行)阅读问题及其相关的回答。

There are several approaches to this (without necessarily slurping). 有几种方法可以解决此问题(不必之以鼻)。 One is to assume that double-quotes do not appear anywhere other than at the beginning or end of the strings of interest. 一种是假定双引号没有出现在感兴趣的字符串的开头或结尾之外的任何地方。 I am not sure how valid an assumption this is which makes the following script fragile. 我不确定这会使以下脚本易碎的假设是否有效。 Note that the last block is invalid because the answer is not enclosed in double quotes. 请注意,最后一个块是无效的,因为答案没有用双引号引起来。

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

Test input: 测试输入:

__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

Output: 输出:

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"

Based on your last comment, I wonder if this is what you want: 根据您的最新评论,我想知道这是否是您想要的:

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

It captures as one item each selection in double quotes, however long. 它会将每个选择的双引号(无论多长时间)捕获为一项。 (To anticipate: George this is A solution, but, no, I didn't choose to use File::Slurp .) (可以预料:George这是一个解决方案,但是,不,我没有选择使用File::Slurp 。)

The operation you are looking for is called 'file slurping' instead of undef-ing $/ 您要查找的操作称为“文件读取”,而不是未定义$ /

use 采用

File::Slurp - Efficient Reading/Writing of Complete Files File :: Slurp-有效读取/写入完整文件

here's the summary from the site 这是该网站的摘要

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

It sounds like you want to read all "double-quoted" values inside a file, including those that are split across lines. 听起来好像您想读取文件中的所有“双引号”值,包括跨行拆分的值。 If that's the case, you can do the following: 如果是这样,您可以执行以下操作:

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

This doesn't handle escaped double-quotes within your quoted values, but your example didn't have any examples of that. 这不能处理您引用的值中的转义双引号,但是您的示例没有任何示例。 If you need to be able to escape quotes, you need to change the regular expression a bit or use Text::Balanced as described above. 如果需要转义引号,则需要稍微更改正则表达式或使用Text :: Balanced,如上所述。

With the OP's clarification that he's trying to get quoted strings out of the file, and assuming that each string's closing quote will be at the end of a line, my approach would be: 随着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!"

Which returns: 哪个返回:

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