0

localを使用するときは、スコープについて多くの検索を行いました。

私はここから理解しています: http://www.perlmonks.org/?node_id=94007「ローカル」行が実行されてから次のブロックの終わりに到達するまでの間、変数の値が一時的に変更されることを理解しています。ただし、perl 読み取りカーソルも「スクロール バック」するようです。以前の $_ を保持しているようです。

これらは、私の perl スクリプトの要件です。

std in で、テキスト ファイルを読み取ります。現在の行が == に一致する場合、その行の文字列を対応する書式 (==、===、==== のそれぞれで異なる書式) を持つ html フラグメントとして出力します。プロパティ名と ! の後の部分として 次まで!値として (複数行にまたがる場合があります)。

サンプル ファイルは次のとおりです。

$ cat dummy_spec.txt
== title1 (level 1) ==
=== title2 (level 2) ===
title2p2 !
2p2_1
!
title2p2 ! Line 1
!
title2p1 ! 
echo "$tam ta" 
!
title2p3 !
2p3
!
title2p2 ! Li
ne split
!
==== title3 (level 3) ====
title3p1 !
one
two
three
!

そして、ここに私のコードがあります:

#!/usr/bin/env perl 
my $propName='';
my $propVal='';
while (<>){
    #print "new loop number $., contents $_ \n";
    $propName='';
    $propVal='';

    my $str=$_;
    chomp $str;

    if ($str=~/==\s+.+\s+==/)#If line is a Category, print category
    {
        $str=~s/=//g;
        print "\t\t\t<tr class=\"category\"><td colspan=\"2\">$str</td></tr>\n";
    } elsif($str=~/===\s+.+\s+===/)#If line is a list, print list title
    {
        $str=~s/=//g;
        print "\t\t\t<tr class=\"list\"><td colspan=\"2\">$str</td></tr>\n";
    } elsif($str=~/====\s+.+\s+====/)#If line is an item, print item title
    {
        $str=~s/=//g;
        print "\t\t\t<tr class=\"item\"><td>$str</td></tr>\n";
    } elsif($str=~/!/)#If line is a property, print name and value
    {
        ($propName,$propVal)=split '!', $_;
        chop $propVal;
        print "This is a property ($.) with name : $propName and first line : $propVal \n";
        local $/ = "!\n";
        if(<>){#custom $/ should still be in scope here.            
            chomp;
            $propVal="$propVal -~- $_";
            print "This is a property ($.) with name : $propName and value : $propVal \n";
        }
    }

}

出力は本来あるべきものではありません:

$ cat dummy_spec.txt |./multi 
            <tr class="category"><td colspan="2"> title1 (level 1) </td></tr>
            <tr class="category"><td colspan="2"> title2 (level 2) </td></tr>
This is a property (3) with name : title2p2  and first line :  
This is a property (4) with name : title2p2  and value :  -~- title2p2  
This is a property (5) with name : title2p2  and first line :  Line 1 
This is a property (6) with name : title2p2  and value :  Line 1 -~- title2p2 ! Line 1

This is a property (7) with name : title2p1  and first line :   
This is a property (8) with name : title2p1  and value :   -~- title2p1 ! 

This is a property (9) with name : title2p3  and first line :  
This is a property (10) with name : title2p3  and value :  -~- title2p3  
This is a property (11) with name : title2p2  and first line :  Li 
This is a property (12) with name : title2p2  and value :  Li -~- title2p2 ! Li

            <tr class="category"><td colspan="2"> title3 (level 3) </td></tr>
This is a property (14) with name : title3p1  and first line :  
This is a property (15) with name : title3p1  and value :  -~- title3p1  

perlの読み取りカーソルも「スクロールバック」するようですか?前の $_ を出力します。

また、私の perl は非常に基本的なものであるため、申し訳ありません。

4

1 に答える 1

3

$_の変更された値でスコープ内に割り当てているのではなく$/、入力から読み取り、読み取り行を if ステートメントの条件として使用するだけです。

$_ファイルから読み取るときの変数への魔法の割り当ては、<>演算子がループの条件の唯一の内容である場合にのみ発生し、ステートメントwhile の条件には適用されません。I/O Operators のドキュメントifの 4 番目の段落を参照してください。

if ステートメントを次のように変更することをお勧めします。

if(defined ($_ = <>))
于 2013-05-30T17:02:32.220 に答える