【问题标题】:Print out preceding lines after regex match在正则表达式匹配后打印出前几行
【发布时间】:2014-12-18 11:16:33
【问题描述】:

我正在编写一个测验程序。我正在使用 .txt 文件作为测试库,但无法弄清楚如何(使用正则表达式)匹配每个问题并在不同的行上打印出可能的答案。我原本只是要做真假,所以我不需要匹配其他任何东西,只要匹配“1”就可以了。基本上我只需要一行的问题和其他行的答案。这是一个问题的例子

1.) some text
 a.) solution 
 b.) solution 
 c.) solution

我之前的代码:

while (<$test>) {

    foreach my $line (split /\n/) {

        my $match1 = "1";

            if ($line =~ /$match1/) {
                $question1 = $line;
                print "$question1\n";
                print "Answer: ";           
                $answer1 = <>;
                chomp ($answer1);
                    if ( $answer1 =~ /(^a$)/i) {
                        $score1 = 20;
                            push @score, $score1;
                    }       
            }

【问题讨论】:

  • 而 只会给你一行。
  • @sln,这取决于$/ 是什么。如果它是未定义的,你会啜饮该文件。但是,您不会在 while 循环中 slurp 文件。但是你可以有特定的记录分隔符。
  • 那么他就不需要while()了。除非他在拆分下方的收盘/开盘中重新使用 $test 。是的,没错,他可以使用一些不命名为换行符的晦涩分隔符。
  • @kspaeth - 有很多方法可以做到这一点。您可以使用 `/../ .. /../ 标志的东西,或者使用 \G 锚或仅使用全局标志(如果 /^\d/ 或不使用)。
  • 你为什么不把你的问题/答案文件分成块(例如,用\n\n分隔),这样你就可以一次打印整个块(包含一个问题和可能的答案),而不是而不是一次读取一行文件?更好的是,为什么不创建一个包含问题、可能解决方案和正确答案的哈希数组的漂亮数据结构呢?例如[ { question =&gt; 'Which way is up?', answers =&gt; { a =&gt; 'This way', b =&gt; 'That way', c =&gt; 'Dunno' }, correct =&gt; 'c' }, { ... }]

标签: regex perl string-matching


【解决方案1】:

我真的不明白你在说什么,所以我写了这个示例程序。

use 5.016;
use strict;
use warnings;
my ( @lines, @questions, $current_question );

sub prompt { 
    my ( $prompt ) = @_;
    print $prompt, ' ';
    STDOUT->flush;
    my $val = <>;
    return $val;
}

QUESTION:
while ( <DATA> ) { 
    if ( my ( $ans ) = m/^=(\w+)/ ) {
        INPUT: { 
            say @lines;
            last unless defined( my $answer = prompt( 'Your answer:' ));
            say '';
             my ( $response ) = $answer =~ /([a-z])\s*$/;
            if ( not $response ) { 
                $answer =~ s/\s*$//; #/
                say "Invalid response. '$answer' is not an answer!\n"; 
                redo INPUT;
            }
            if ( $response eq $ans ) { 
                say 'You are right!';
            }
            elsif ( my $ansln = $current_question->{$response} ) { 
                if ( $response eq 'q' ) { 
                    say 'Quitting...';
                    last QUESTION;
                }
                say <<"END_SAY";
You chose:\n$current_question->{$response}
The correct answer was:\n$current_question->{$ans}
END_SAY
            }
            else { 
                say "Invalid response. '$response' is not an answer!\n";
                redo INPUT;
            }
        };
        @lines = ();
        prompt( 'Press enter to continue.' );
        say '';
    }
    else { 
        if ( my ( $qn, $q ) = m/^\s*(\d+)\.\)\s+(.*\S)\s*$/ ) { 
            push @questions, $current_question = { question => $q };
        }
        else {
            my ( $l, $a ) = m/^\s+([a-z])/;
            $current_question->{$l} = ( m/(.*)/ )[0];
        }
        push @lines, $_;
    }
}

__DATA__
1.) Perl is
  a.) essential
  b.) fun
  c.) useful
=c
2.) This question is
 a.) Number two
 b.) A test to see how this format is parsed.
 c.) Unneeded
=b

【讨论】:

    【解决方案2】:

    这可能过于简化了。
    它只是读取测试数据并创建一个结构。
    您可以使用它来对应试者的答案进行评分。

    use strict;
    use warnings;
    
    use Data::Dumper;
    
    $/ = undef;
    
    my $testdata = <DATA>;
    
    my %HashTest = ();
    my $hchoices;
    my $hqeustion;
    my $is_question = 0;
    
    while ( $testdata =~ /(^.*)\n/mg )
    {
        my $line = $1;
        $line =~ s/^\s+|\s+$//g;
        next if ( length( $line ) == 0);
    
        if ( $line =~ /^(\d+)\s*\.\s*\)\s*(.*)/ )
        {
           $is_question = 1;
           $HashTest{ $1 }{'question'} = $2;
           $HashTest{ $1 }{'choices'}  = {};
           $HashTest{ $1 }{'answer'}  = 'unknown';
    
           $hqeustion = $HashTest{ $1 };
           $hchoices  = $HashTest{ $1 }{'choices'};
        }
        elsif ( $is_question && $line =~ /^\s*(answer)\s*:\s*([a-z])/ )
        {
            $hqeustion->{'answer'} = $2;
        }
        elsif ( $is_question && $line =~ /^\s*([a-z])\s*\.\s*\)\s*(.*)/ )
        {
            $hchoices->{ $1 } = $2;
        }
    }
    
    print "\nQ & A summary\n-------------------------\n";
    
    for my $qnum ( keys %HashTest )
    {
        print "Question $qnum:  $HashTest{$qnum}{'question'}'\n";
        my $ans_code = $HashTest{$qnum}{'answer'};
        print "Answer: ($ans_code)  $HashTest{$qnum}{'choices'}{$ans_code}\n\n";
    }
    
    print "---------------------------\n";
    print Dumper(\%HashTest);
    
    
    __DATA__
    
    1.) What is the diameter of the earth?
     a.) Half the distance to the sun 
     b.) Same as the moon 
     c.) 6,000 miles
     answer: c
    
    2.) Who is buried in Grants Tomb?
     a.) Thomas Edison 
     b.) Grant, who else 
     c.) Jimi Hendrix
     answer: b
    

    输出:

    Q & A summary
    -------------------------
    Question 1:  What is the diameter of the earth?'
    Answer: (c)  6,000 miles
    
    Question 2:  Who is buried in Grants Tomb?'
    Answer: (b)  Grant, who else
    
    ---------------------------
    $VAR1 = {
              '1' => {
                       'question' => 'What is the diameter of the earth?',
                       'answer' => 'c',
                       'choices' => {
                                      'c' => '6,000 miles',
                                      'a' => 'Half the distance to the sun',
                                      'b' => 'Same as the moon'
                                    }
                     },
              '2' => {
                       'question' => 'Who is buried in Grants Tomb?',
                       'answer' => 'b',
                       'choices' => {
                                      'c' => 'Jimi Hendrix',
                                      'a' => 'Thomas Edison',
                                      'b' => 'Grant, who else'
                                    }
                     }
            };
    

    【讨论】:

      猜你喜欢
      • 2022-11-02
      • 2015-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多