Если вы не можете гарантировать, что первая координата всегда будет уникальной, идея пары лучше представить как отдельный массив из двух элементов. Вы также можете значительно расширить ту же идею до кортежей более высоких размеров.
#!/usr/bin/perl
use strict; use warnings;
use Data::Dumper;
my @tuples = ([qw(A P)], [qw(B Q)], [qw(C R)]);
my $re_tmpl = '^%s.*%s=(.)';
my @re = map qr/$_/, map sprintf($re_tmpl, @$_), @tuples;
while (my $line = <DATA>) {
last unless $line =~ /\S/;
my ($value) = map { $line =~ $_ } @re;
print $value, "\n";
}
__DATA__
A P=1 Q=2 R=3
B P=8 Q=2 R=7
C Q=2 P=1 R=3
Но, с методом и описанным выше способом, вы выполняете несколько операций матч, чем это необходимо (три на каждой строке, а не одну). Это делает @eugene's answer более эффективным.
Более общее решение заключается в использовании:
#!/usr/bin/perl
use strict; use warnings;
my @tuples = ([qw(A P)], [qw(B Q)], [qw(C R)]);
my $re_tmpl = '^%s.*%s=(.)';
my %re;
@re{ map $_->[0], @tuples } = map qr/$_/,
map sprintf($re_tmpl, @$_),
@tuples;
while (my $line = <DATA>) {
last unless $line =~ /\S/;
my ($value) = $line =~ $re{substr $line, 0, 1};
print $value, "\n";
}
__DATA__
A P=1 Q=2 R=3
B P=8 Q=2 R=7
C Q=2 P=1 R=3
Хорошая вещь об этом вы можете адаптировать его для кортежей размеров больше, чем два.
Кроме того, теперь, когда вы выбираете шаблон на основе первого символа линии, узоры сами становятся проще:
#!/usr/bin/perl
use strict; use warnings;
my @tuples = ([qw(A P)], [qw(B Q)], [qw(C R)]);
my $re_tmpl = '%s=(.)';
my %re;
@re{ map $_->[0], @tuples } = map qr/$_/,
map sprintf($re_tmpl, $_->[1]),
@tuples;
while (my $line = <DATA>) {
last unless $line =~ /\S/;
my ($value) = $line =~ $re{substr $line, 0, 1};
print $value, "\n";
}
__DATA__
A P=1 Q=2 R=3
B P=8 Q=2 R=7
C Q=2 P=1 R=3
Более простой альтернативой (что влечет за собой захват всех x=y
) является:
#!/usr/bin/perl
use strict; use warnings;
my %pairs = qw(A P B Q C R);
my $re = qr/([A-Z])=([0-9])/;
while (my $line = <DATA>) {
last unless $line =~ /\S/;
my $type = substr $line, 0, 1;
my $value = { $line =~ /$re/g }->{ $pairs{$type} };
print "$value\n";
}
__DATA__
A P=1 Q=2 R=3
B P=8 Q=2 R=7
C Q=2 P=1 R=3
это последнее также позволяет легко вывести несколько значений из строки:
#!/usr/bin/perl
use strict; use warnings;
my %tuples = (A => [qw(P Q)], B => [qw(Q R)], C => [qw(P R)]);
my $re = qr/([A-Z])=([0-9])/;
while (my $line = <DATA>) {
last unless $line =~ /\S/;
my $type = substr $line, 0, 1;
my @values = @{ { $line =~ /$re/g } }{ @{ $tuples{$type} } };
print "@values\n";
}
__DATA__
A P=1 Q=2 R=3
B P=8 Q=2 R=7
C Q=2 P=1 R=3
Вам не нужен синтаксис хэша для создания хэша. `% h = qw/A P B Q C R /;` будет работать так же долго, как и четное количество элементов. – Sorpigal 2010-12-17 12:18:21
+1 Спасибо, что указали это. – RedGrittyBrick 2010-12-17 12:24:47