Perl脚本卡在if语句上

时间:2014-10-24 16:08:29

标签: perl

我是Perl的初学者(这是我练习手册以外的第二个脚本),我似乎在使if语句工作时遇到了一些麻烦。

该脚本用于读取文档,取一行,解析一个有用的表(以文本序列开头并以>结尾的部分),然后将其打印到屏幕上。

打印$line后打印第一个文本序列(第20行)后似乎卡住了。我添加了"只需检查"以确定问题发生的位置。这只是我想念的简单事物,还是我的基本程序逻辑存在缺陷?

use strict;
use warnings;

print "What file would you like to open? \n";
my $file = <STDIN>;
chop($file);
open( FILE, $file ) || die("Can not open $file");
while (<FILE>) {
    my $bool = 0;
    my $line = $_;
    chop $line;
    if ( !( $line =~ /text input/ ) && ( $bool == 0 ) ) {
        next;
    } elsif ( ( $line =~ /text input/ ) && ( $bool == 0 ) ) {
        $bool = 1;
        print $line;
        next;
    }
    if ( ( $line =~ /^\s$/ ) && ( $bool == 1 ) ) {
        print "just checking";
        next;
    }
    if ( !( $line =~ /^>/ ) && ( $bool == 1 ) ) {
        my @table = split( /\s{2,}/, my $table );
        foreach (@table) {
            print "$_ \n";
        }
        if ( ( $line =~ /^>/ ) && ( $bool == 1 ) ) {
            print "last function ok";
            last;
        }
    }
}
close($file);
exit;

4 个答案:

答案 0 :(得分:3)

有几点可能会导致脚本出现问题:

my @table = split(/\s{2,}/, my $table);

在这里,你要分割一个新初始化的变量,所以你永远不会得到任何输出。您可能希望拆分$line,而不是$table

while (<FILE>)
{
    my $bool = 0;
    ...
    elsif (($line  =~ /text input/) && ($bool == 0))
        {
        $bool = 1;
        next;
        }

你在每个循环开始时将$bool设置为0,这一行改变了$bool的值,跳过了循环的其余部分,因此没有任何条件{ {1}}将进行测试。 $bool == 1应该在while循环之外。

my $bool = 0

您可以使用if (!($line =~ /^>/) ... if (!($line =~/text input/ ... 检查该行是否以$line !~ /^>/>开头。

$line !~ /text input/

如果您要取消结尾,chop $line; 将删除unix,win和mac line endings。

您可以利用速记来评估chomp的价值,只需输入

即可
$bool

Perl将if ($bool) 评估为false,将0评估为true,这样每次使用时,您至少可以保存5个字符,以评估1是否为$bool。{{ 1}}将保存三个字符的输入,但它看起来更酷,你不觉得吗?

如果仍未解决问题,则必须发布输入内容,因为很难知道何时打印表格。

答案 1 :(得分:2)

下面:

while (<FILE>)
{
    my $bool = 0;
    my $line = $_;
    chop $line;
    if (!($line =~/text input/) && ($bool == 0))
此时

$bool将始终为0。我猜你也许是想在 while while循环中声明并初始化它,所以它会持续存在多行?

答案 2 :(得分:2)

看起来你想处理两种模式之间的界限。

您可以使用状态变量$bool来执行此操作,但您需要在文件处理循环之外声明该状态变量。目前,它正在每行之前重新初始化为0

但是,作为一种快捷方式,您可以使用Flip-Flop Operator ..查找两种模式之间的行。

以下是您的脚本的清理:

use strict;
use warnings;
use autodie;

print "What file would you like to open? \n";
chomp( my $file = <STDIN> );

open my $fh, '<', $file;

while (<$fh>) {
    if ( /text input/ ... /^>/ ) {
        print;
    }
}

注意:

  • Range或Flip-Flop运算符返回一个递增值,可用于了解您所在匹配项的行号。
  • 我使用范围...的较长形式,因为我想要对结束条件进行延迟测试。这是因为text input行在开头包含>

与往常一样,在使用新的运算符或功能之前,请详细阅读文档。

答案 3 :(得分:0)

这些行也有问题

    if (!($line =~ /^>/) && ($bool == 1))
        {
        my @table = split(/\s{2,}/, my $table);
                foreach(@table){
                    print "$_ \n";
                }
    if (($line =~ /^>/) && ($bool == 1))
        {
        print "last function ok";
        last;
        }
}

最后一个花括号错位,你永远不会去print "last function ok";

    if ($line !~ /^>/ && $bool) {
        my @table = split(/\s{2,}/, $line);
        foreach (@table) {
            print "$_ \n";
        }
    } # <=== here 
    if ($line =~ /^>/ && $bool) {
        print "last function ok\n";
        last;
    }