Проблемы довольно прост: Вы используете $1
, $2
и $3
в вашей программе, но к тому времени, когда вы используете их, вы потеряли свою ценность. Это глобальные символы, и они заменяются всякий раз, когда вы используете оператор регулярного выражения. После вашего первого регулярного выражения просто сохраните их в другой переменной:
$first = $1;
$second = $2;
$third = $3;
Вы также должны быть осторожны с регулярными выражениями. Ваши регулярные выражения работают, но они очень, очень узкие. Я пропустил это в первый раз, когда у вас были вкладки в ваших файлах. Мне нравится использовать \s+
для пробелов любого типа. Это будет охватывать несколько вкладок или пробелов или комбинацию разных.
Я также настоятельно рекомендую вам узнать еще modern Perl. Вы бы сразу поднял эту проблему, если бы вы использовали эти две строки в программе:
use strict;
use warnings;
strict
бы убедиться, что вы определили переменные через my
или our
. Это гарантирует, что вы не скажете $Foo
в одном месте и $foo
еще и задаетесь вопросом, что произошло со значением, которое вы сохранили в $foo
.
warnings
было бы сразу подсвечено, что $1
и $2
не имеют значений, когда вы выполняете свое второе регулярное выражение.
Из-за require
вещи немного липкие в описании переменных, когда вы используете strict
. A my
переменная является строго локальной переменной с ограниченным объемом. Вот почему он используется в 99% случаев.
A my
Переменная существует только в области, которую она объявила. Например, если вы объявляете переменную внутри цикла, она не существует вне цикла:
if ($a > $b) {
my $highest = $a;
}
else {
my $highest = $b;
}
print "The highest value is $highest\n";
Это не будет работать, потому что $highest
определяется внутри, если заявление. Вы должны объявить $highest
вне заявления для его работы:
my $highest;
if ($a > $b) {
$highest = $a;
}
else {
$highest = $b;
}
print "The highest value is $highest\n";
our
объявлена переменная доступна по всему миру для всего пакета . Вы определяете его где угодно - внутри цикла, внутри оператора if, где угодно - и он будет доступен позже.
Пакет - просто пространство имен. Если вы не заявили об обратном, вы всегда находитесь в пакете main
. Полезно, чтобы переменные модуля не влияли на переменные в вашем коде. Таким образом, ваш включенный модуль может использовать переменную $foo
, и вы можете использовать переменную $foo
, не мешая друг другу.
Причина, по которой я должен был войти в это из-за вашего require
. Переменная A my
доступна только в ее объеме. То есть цикл for, оператор if или весь файл. Обратите внимание, что последний: Весь файл. Это означает, что если я сделаю my %h1
, он не будет существовать вне файла. Таким образом, я должен объявить его с our
.
Кроме того, когда вы используете strict
, это довольно чертовски строго. Он генерирует ошибку времени компиляции, когда видит переменную, которая не была объявлена. Таким образом, я должен объявить %h1
внутри основной программы, поэтому компилятор знает об этом.
Я также использую заявление say
, которое я получаю от своего use feature qw(say);
. Это как print
, за исключением того, что он всегда печатает символ NL. Это не похоже на много, но во многих случаях это может быть намного менее беспорядочно.
Настоятельно рекомендуется использовать объявленный скаляр для открытия файла, а не только дескриптор файла. Файловые дескрипторы являются глобальными и могут вызвать проблемы. Кроме того, трудно использовать дескриптор файла в подпрограмме. Кроме того, рекомендуется использовать трехпозиционный открытый оператор. Это предотвращает проблемы, когда имена файлов начинаются с >
или |
.
Вот программа, переписанная с немного более современным чувством Perl. Я сохранил ваш стандартный алгоритм, но добавил новые прагмы, объявленный %h1
до require
ing, и использовал более стандартный open
. В противном случае, это в значительной степени то, что у вас было.
#! /usr/bin/env perl
#
use strict;
use warnings;
use feature qw(say);
our %h1;
require "hash.pl";
open (my $input_fh, "<", "input.txt")
or die "can't open file: $! \n";
foreach my $amp (<$input_fh>) {
chomp $amp;
if ($amp =~ /(\d+)\s+(\d+)\s+(\d+)/) {
# Got to save the $1, $2, and $3 for later
my $first = $1;
my $second = $2;
my $third = $3;
foreach my $key (keys %h1) {
foreach my $tmp1 (@{$h1{$key}}) {
if ($tmp1 =~ /($first\s+$second|$second\s+$first)/) {
say qq("$key": "$third");
}
}
}
}
}
close $input_fh;
В чем проблема? – ArjunShankar