为什么这个模式与我的程序从STDIN读取的数据不匹配?

时间:2010-02-15 13:08:01

标签: regex perl

假设有一个使用<STDIN>

从控制台输入的列表
@string = <STDIN>;

现在,我在我的程序中检查一个模式,比如说/manu/

foreach (@string)
{
    if(/manu/)
    {
        print $_."\n";
    }
}

代码无法查找模式/manu/

然而,当我执行以下操作时,代码完全正常:

chomp(@string = <STDIN>);

为什么?

3 个答案:

答案 0 :(得分:9)

编辑:我的原始答案是在假设发布的代码是OP使用的代码的情况下编写的。更正后更新。

这是我跑步时得到的:

#!/usr/bin/perl

use strict; use warnings;

my @string = <STDIN>;

for (@string) {
    if(/manu/) {
        print "'$_'";
    }
}

输出:

E:\> t
manu
nana
tada
^Z
'manu
'

注意 Control-Z 我用来在Windows上命令行发出EOF信号(如果你使用的是* nix shell,你可以使用 Control-D )。

只有当您的程序读取可以从STDIN读取的所有数据时,才会显示输出。

请注意manu后打印的换行符。那是因为我没有chomp输入。这是使用此代码与使用

之间的唯一区别
chomp(my @string = <STDIN>)

当您第一次将<STDIN>分配给一个数组并对其进行迭代时,您的程序将等待,直到没有更多数据要读取其内存使用量将与该数量成比例收到的数据。

另一方面,以下程序将处理行:

/manu/ and print while <>;

并且其内存使用量将与收到的最长行成比例。

以上一行相当于:

while ( <> ) {
    if ( /manu/ ) {
        print $_;
    }
}

请注意,您应始终将use strict;及其好友use warnings;添加到您的脚本中。请参阅perldoc strict

答案 1 :(得分:3)

在您的第一个示例中,@list未定义。如果你有的话

use strict;
use warnings;

在你的脚本中(强烈推荐!),Perl会告诉你这个。

编辑:现在您已修复此问题,您可以使用的代码。

答案 2 :(得分:-1)

选择撕掉任何空格或cr / lfs。添加一个chomp,或在你的正则表达式匹配中添加任何空格,例如:

foreach (@string)
{
    if(/manu\s*/)
    {
        print $_."\n";
    }
}