在Perl中,如何从STDIN读取直到遇到空格或换行符?

3
在Perl中,我只熟悉使用通常的操作。
chomp(my $ip = <>);

如果这个$ip是由空格分隔的单词,那么我需要使用split方法来获取“words”,“separated”,“by”和“space”。有没有一种方法可以从一开始逐个读取单词呢?
2个回答

6

将输入记录分隔符 $ / 设置为空格,可以逐字阅读。 您可能会发现结果与直觉相反,请小心所求

例如尝试:

perl -nwe 'BEGIN { $/ = " ";} print "Line: $_"'

它将从标准输入读取,并将其逐个单词地打印回给您。但是,正如您所注意到的那样,换行符(按ENTER键)仍然是该过程中相当重要的一部分。
然而,$/ 无法智能化。它只是我们用来区分输入记录的字符(或字符集),并且它会影响除STDIN之外的许多其他事情,因此使用它很可能会使您感到困惑。除非当然,您在本地使用它,并且仅在您想要的地方使用它。
{  # make this part lexically scoped
    local $/ = " ";  # use local version of $/
    while (<>) {
        chomp(my $ip = $_);  # note that chomp removes space instead
    }
}  # End of scope, $/ is back to normal

4
您可以将输入记录分隔符 $/ 更改为空格。(我不建议这样做,读到最后)
#!/usr/bin/perl
use strict;

open(my $in, "<", "data.txt") or die "can't open input: $!";
local $/ = " ";
while(<$in>) {
    chomp;
    print "\'$_\'\n";
}

在这种情况下,输入会被空格分隔但不包括换行符。类似地,chomp使用记录分隔符的值,因此对于多行文本,您将得到以下结果:

  • 行末单词与下一行单词开头没有分隔。您可以通过在行末加上空格来解决这个问题,但这样做不太方便。
  • 您仍然需要摆脱换行符,但chomp命令无法去除它。

因此,最终,如果您有多行文本,则通常最好保留默认记录分隔符并将每行文本拆分为单词。


1
注意:你应该养成始终使用 use warnings 的习惯。在双引号字符串中(反之亦然),你不必转义单引号 '。此外,以这种方式使用 local 没有实际用途,因为这个局部变量的作用域仍将是全局的。 - TLP
local 使其在文件中成为局部变量,这正是预期的。但将其封装在一个块中是更好的实践,我同意。 - voidengine
文件作用域只有在存在多个文件时才有意义。 - Brad Gilbert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接