Perl 跳出 while 循环,打印结果,然后重新启动循环

问题描述 投票:0回答:1

$combatblock = "$name:$dex:$db:$mp:$hp"; 我在 Debian Linux 12 上使用 Perl 5.36,并正在为角色扮演游戏编写一个实用程序。这不是一个与工作相关的项目,因为我更像是一个业余爱好者而不是一个认真的程序员,所以如果这不是一个真正合适的请求,我深表歉意。

我的输入文件如下所示:

Name: orc of power normal
mw_monsters normal
Stats: STR [14] CON [10] SIZ [10] INT [8] POW [8] DEX [15] APP [8] EDU [5] 
SCB: Physical=7 Communication=4 Knowledge=4 Manipulation=8 Perception=5 
Combat: Hit Points=10 Major Wound Level=5 Armour=
Initiative:
Stat Rolls: Effort 70% Stamina 50% Idea 40% Luck 40% Agility 75% Charisma 40% Know 25% 
Derived: MP=8 XP=4 FP=24 SAN=40% DB=NONE  MOV [10]
Skills:  Scimitar 42% Composite Bow 42% Short Spear 42% Short Spear (thrown) 42% Spiked Shield 42% Climb 62% Dodge 47% Hide 42% Lore (Orc-lore) 39% Language (Human) 29% Language (Orcish) 64% Ride (warboar) 57% Sense 40% Search 50% Move Quietly 47% Track 35%
 ++ Distribute 40% to ONE skill and 20% to THREE skills
Powers: 
This orc is not a sorcerer.
Possessions:
Notes:

我想选择这些行的某些部分并产生如下输出:

Name:DEX:DB:MP:HP:Current:
orc:[15]:DB=NONE:MP=8:Points=10

这是我到目前为止的代码:

#!/usr/bin/env perl

use strict;
use warnings;

my $line;
my $combatblock = "";
my $name = "";
my $dex = "";
my $db = "";
my $mp = "";
my $hp = "";

my @combatarray;
my @nameline;
my @statline;
my @hpline;
my @derivedline;

print "Name:DEX:DB:MP:HP:Current:\n";

while ($line = <>)
{
    chomp $line;

    if ($line =~ "Name") {
        @nameline = split (/ /,$line);
        $name=$nameline[1]; # Name
    #   print " ++ $name\n";
    #   $combatblock = "$name:";
    };

    if ($line =~ "STR") {
        @statline = split (/ /,$line);
        $dex=$statline[12]; # DEX for initiative
    #   print " ++ $dex\n";
    #   $combatblock = "$combatblock:$dex:";
    };

    if ($line =~ "Derived") {
        @derivedline = split (/ /,$line);
        $db=$derivedline[5]; # Damage Bonus
        $mp=$derivedline[1]; # Magic Points
    #   print " ++ $db\n";
    #   print " ++ $mp\n";
    #   $combatblock = "$combatblock:$db:$mp:";
    };

    if ($line =~ "Hit Points") {
        @hpline = split (/ /,$line);
        $hp=$hpline[2]; # Hitpoints
    #   print " ++ $hp\n";
    #   $combatblock = "$combatblock:$hp:";
    };
    $combatblock = "$name:$dex:$db:$mp:$hp";
    print "$combatblock\n"; # This can be commented out to get rid of unnecessary output

};
print "Result $combatblock\n"; # Result can be taken out of this line

它生成的是这样的:

61 colin@kuu> combatstatblock.pl < orc.txt
Name:DEX:DB:MP:HP:Current:
orc::::
orc::::
orc:[15]:::
orc:[15]:::
orc:[15]:::Points=10
orc:[15]:::Points=10
orc:[15]:::Points=10
orc:[15]:DB=NONE:MP=8:Points=10
orc:[15]:DB=NONE:MP=8:Points=10
orc:[15]:DB=NONE:MP=8:Points=10
orc:[15]:DB=NONE:MP=8:Points=10
orc:[15]:DB=NONE:MP=8:Points=10
orc:[15]:DB=NONE:MP=8:Points=10
orc:[15]:DB=NONE:MP=8:Points=10
Result orc:[15]:DB=NONE:MP=8:Points=10
62 colin@kuu> 

现在,我明白这实际上是在做它所写的事情。正如上面的注释字符串中所述,我可以取出“

print "$combatblock\n";
”来删除所有其他输出,只留下“Result”行。

这个脚本应该处理更多的“orc”统计数据并产生如下输出:

Name:DEX:DB:MP:HP:Current:
orc:[15]:DB=NONE:MP=8:Points=10
orc:[19]:DB=NONE:MP=13:Points=10
orc:[12]:DB=+1D4:MP=10:Points=12

...通过输入文件依此类推。

发生的情况是,仅打印最后一个结果(在本例中为

orc:[12]
):while 循环覆盖了
$combatblock
的先前值。

如何跳出 while 循环,打印“Result”行,然后返回到 while 循环的顶部来处理下一组“orc”统计数据?

我已经尝试过:

  • 将 $combatblock 写入文件,以便我可以“cat”控制台上的输出
  • "if ($line =~"
    语句嵌套在另一个 foreach 或 while 循环中
  • 使用
    @combatarray
    结构将
    $combatblock
    推到
  • 在“
    $combatblock
    ”语句中生成
    if
    ,其中包含诸如“
    $combatblock = "$combatblock:$db:$mp:""
    ”之类的行(在上面的脚本中已注释掉)

似乎没有什么可以解决“while 覆盖以前的值”问题。我很确定解决方案非常简单,但我就是找不到前进的方法。

任何帮助将不胜感激。

perl variables while-loop
1个回答
0
投票

您可以通过以下方式实现:

push
将每个
if condition
处的变量存储为数组,并在 while 循环内的所有 if 条件结束时打印并重置
array

但是您需要重新访问代码以了解如何从输入文件中提取所需的

strings

 #!/usr/bin/env perl
    use strict;
    use warnings;

    my $line;
    my $combatblock = "";
    my $name = "";
    my $dex = "";
    my $db = "";
    my $mp = "";
    my $hp = "";

    my @combatarray;
    my @nameline;
    my @statline;
    my @hpline;
    my @derivedline;

    print "Name:DEX:DB:MP:HP:Current:\n";

    while ($line = <>)
    {

    chomp $line;

    if ($line =~ "Name") {
        @nameline = split (/ /,$line);
        $name=$nameline[1]; # Name
    #   print " ++ $name\n";
        $combatblock = "$name:";
    push (@combatarray, $combatblock)
    
    };

    if ($line =~ "STR") {
        @statline = split (/ /,$line);
        $dex=$statline[12]; # DEX for initiative
    #   print " ++ $dex\n";
       $combatblock = "$dex:";
    push (@combatarray, $combatblock)
    };

    if ($line =~ "Derived") {
        @derivedline = split (/ /,$line);
        $db=$derivedline[5]; # Damage Bonus
        $mp=$derivedline[1]; # Magic Points
    #   print " ++ $db\n";
    #   print " ++ $mp\n";
       $combatblock = "$db:$mp:";
    push (@combatarray, $combatblock)
    };

    if ($line =~ "Hit Points") {
        @hpline = split (/ /,$line);
        $hp=$hpline[2]; # Hitpoints
    #   print " ++ $hp\n";
       $combatblock = "$hp:";
    push (@combatarray, $combatblock)
    };
#$combatblock = "$name:$dex:$db:$mp:$hp";
print "@combatarray";
@combatarray = ();
};
#print "Result $combatblock\n"; # Result can be taken out of this line
© www.soinside.com 2019 - 2024. All rights reserved.