Wait the light to fall

正则表达式一例

焉知非鱼

以指定音量随机播放音频文件:

my %v;                                 # hash to hold data
my token filename    { .+? \.\S\S\S }; # filenames end in .???
my token volume      { \d+ };          # any digits for volume
my regex extra       { .+ \S };        # anything following that
my $mixer          = 'mixer';
my $player         = 'mplayer -vf dsize=600:-2 -geometry +200-10 ';
my $lockfile       = '/tmp/myplayer';

$lockfile.IO.spurt( $*PID );          # store the process ID so other process can kill this one
END { $lockfile.IO.unlink; }          # remove the lockfile at end

for $=finish.lines {                  # loop through the lines below '=begin finish'
    last if /STOP/;                   # stop at a STOP line
    if m/     (<filename>)
          \s+ (<volume>)
          \s* (<extra>?) / {          # use the regexes/tokens
        my ( $m, $v, $e ) = $/[0..2]; # get captured values from $/
        if $m and $v {                # if there's a filename and volume
            %v{$m}<v> ~= $v;          #   store it in the hash
            %v{$m}<e> ~= $e // '';    #   with any extra arguments
        }}} # lisp-y to save lines
for %v.keys.pick(*) -> $m {           # loop randomly through keys
    say "Playing $m";
    print qqx{ $mixer  %v{$m}<v>      };  # set the volume
    print qqx{ $player %v{$m}<e> "$m" };  # play the file
}

# the rest is like a Perl5 __DATA__ section
=finish
300.avi 77
Crystal Skull Rifftrax.avi 77 -aid 2
Star Trek 5.avi 77
Star Trek 7.avi
aeon-flux.avi 93

改进版:

my @mixer          = 'mixer';
my @player         = < m6player -vf dsize=600:-2 -geometry +200-10 >;
my $lockfile       = '/tmp/myplayer';

$lockfile.IO.spurt( $*PID );

END { $lockfile.IO.unlink; }

my token filename    { .+? \.\S\S\S };
my token volume      { \d+ };
my regex extra       { .* };

my %song-data;

for $=finish.lines {
    last if /^ \s* STOP \s* $/;
    next unless  m/ \s* <filename> \s+ <volume> <extra> /;
    # $<extra> is short for $/{'extra'}
    %song-data{~$<filename>}<v e> = +$<volume>, [$<extra>.words];
}

# uses sub-signature unpacking

for %song-data.pick(*) -> ( :key($m), :value($) (:$v,:@e)) {
    say "Playing $m";
    print run( @mixer,  $v,     :out ).out.slurp-rest.indent(4);
    print run( @player, @e, $m, :out ).out.slurp-rest.indent(4);

}

=finish
300.avi 77
Crystal Skull Rifftrax.avi 77 -aid 2
Star Trek 5.avi 77
Star Trek 7.avi
aeon-flux.avi 93